@ai-ecoverse/slicc-agent 5.3.0 → 5.4.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 +3 -4
- package/dist/client.js +4 -13
- package/dist/client.js.map +2 -2
- package/dist/guests/client.js +4 -16
- package/dist/guests/client.js.map +2 -2
- package/dist/index.js +1 -2
- package/dist/index.js.map +2 -2
- package/dist/spectrum/agent-port.js +0 -5
- package/dist/spectrum/agent-port.js.map +2 -2
- package/dist/spectrum/approvals-port.js +1 -1
- package/dist/spectrum/approvals-port.js.map +2 -2
- package/dist/spectrum/guest-port.js +1 -2
- package/dist/spectrum/guest-port.js.map +2 -2
- package/dist/spectrum/index.js +1 -5
- package/dist/spectrum/index.js.map +2 -2
- package/dist/spectrum/notices-port.js +2 -17
- package/dist/spectrum/notices-port.js.map +2 -2
- package/dist/types/client.d.ts +0 -1
- package/dist/types/guests/client.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/spectrum/agent-port.d.ts +0 -2
- package/dist/types/spectrum/index.d.ts +1 -1
- package/dist/types/spectrum/notices-port.d.ts +1 -3
- package/dist/types/wire.d.ts +0 -7
- package/dist/wire.js +2 -12
- package/dist/wire.js.map +2 -2
- package/package.json +2 -3
- package/dist/mismatch.js +0 -41
- package/dist/mismatch.js.map +0 -7
- package/dist/types/mismatch.d.ts +0 -3
package/README.md
CHANGED
|
@@ -35,8 +35,7 @@ await agent.prompt('What is in /home?');
|
|
|
35
35
|
- **What a view-only connection can do:** it sees the transcript, the agents, settings state and remote-control `watch`, and may call `wait` and `changesOpen`.
|
|
36
36
|
- **What it can't:** every other `AgentControl` method, settings action and remote-control `prompt` or `abort` is refused with `EACCES` ("this follower can watch, but not send, steer or abort"). Send and compact answer `accepted: false` with that code. The `view` seat's variants don't have those methods at all (`view` for control and settings, `watch` for remote control, `none` for Panels); the follower's client answers the missing ones with the refusals ([`src/readonly.ts`](src/readonly.ts)), so the worker never runs them. A `watch` stream is readable only over the link that opened it.
|
|
37
37
|
- **Carrying the connection over a byte stream:** `linkEndpoint({ write, close })` is a `PortEndpoint` that `connectAgent` accepts. Feed it the stream's bytes with `receive(bytes)` and its end with `end(error?)`. On the owner's side, `bridgePort(port, { write, close })` does the same for the `MessagePort` from `port()`.
|
|
38
|
-
- **The bytes:** the owner first posts a hello,
|
|
39
|
-
- **Another agent version:** a follower whose owner greets with another link protocol (an agent before 5.0 greets with its bare server id, which reads as protocol 1), or whose contracts don't cover the follower's (`contract_mismatch`), closes the link at once and gets a connection whose `mismatch` is a sentence such as "That SLICC runs an older version of the agent than this one, so this tab can't follow it. Update that SLICC, then reload this page." Its states are empty, every call rejects with `EPROTO` and that sentence, and `closed` stays pending, so a follower that retries on close doesn't loop. The spectrum adapter puts the tab in watch-only mode (`AgentAdapter.readOnly()` is "Watch only."), so it has no composer and no cone actions, and `notices` lists a banner with the sentence that can't be dismissed (`agent-mismatch`, spectrum 1.75 on); nothing reaches the owner. A 4.x follower from 4.3.2 on reads the 5.x hello the same way and shows "That SLICC runs a newer version of the agent than this one, so this tab can't follow it. Update this SLICC, then reload this page."; an older one only sees the link close.
|
|
38
|
+
- **The bytes:** the owner first posts a hello, its server id, then each Chord frame travels as its JSON text in UTF-8 (`PortLink` in [`src/wire.ts`](src/wire.ts)), and `{ close: true }` ends the port. On a byte stream each message becomes a frame: a `u32` big-endian length, then a tag (0 data, 1 hello, 2 close), then the payload. A frame is at most 16 MiB, and a malformed one ends the link.
|
|
40
39
|
|
|
41
40
|
### Bash and files on slicc-kernel
|
|
42
41
|
|
|
@@ -643,7 +642,7 @@ An `agent` item is answered by the judge ([`src/approvals/judge.ts`](src/approva
|
|
|
643
642
|
|
|
644
643
|
A guest seat (plan D13, PR 19) is a revocable seat on one cone: the guest sees that cone's live transcript and has a composer, and nothing else.
|
|
645
644
|
|
|
646
|
-
- **Minting.** The tray hub mints the seat and its one-time URL (v6's routes, D10); the page hands the agent adapter its routes: `createAgentModel(connection, { guests: { mint({ label, expiresAt, gates, agentId }) → { id, url }, revoke(id) } })`. Its `guests` port (spectrum's `GuestPort`) mints through the hub, then opens the seat in the worker with `AgentControl.guestOpen({ id, label, agentId, expiresAt, gates })`; if the worker refuses, the hub's seat is revoked again. `list()` is the transcript's `guests` state (`{ id, label, agentId, createdAt, expiresAt, gates, connected, pending }`), and the URL is returned once and never kept. `unavailable()` says "Inviting guests needs the tray hub." without a hub, and "Only a tab with Control can invite guests." on a view-only follower
|
|
645
|
+
- **Minting.** The tray hub mints the seat and its one-time URL (v6's routes, D10); the page hands the agent adapter its routes: `createAgentModel(connection, { guests: { mint({ label, expiresAt, gates, agentId }) → { id, url }, revoke(id) } })`. Its `guests` port (spectrum's `GuestPort`) mints through the hub, then opens the seat in the worker with `AgentControl.guestOpen({ id, label, agentId, expiresAt, gates })`; if the worker refuses, the hub's seat is revoked again. `list()` is the transcript's `guests` state (`{ id, label, agentId, createdAt, expiresAt, gates, connected, pending }`), and the URL is returned once and never kept. `unavailable()` says "Inviting guests needs the tray hub." without a hub, and "Only a tab with Control can invite guests." on a view-only follower or a guest.
|
|
647
646
|
- **The record.** Seats live in the session document `slicc.guests`, so they survive reloads and restarts: id, label (control characters stripped, at most 64 characters), cone, expiry (at most 30 days), the two gates (`user`, `agent`, `cone`, `scoop:<name>` or `off`, fixed when the seat is opened; the tools gate can't be `off` or `cone`, from any caller, so a guest's run never uses tools unreviewed: "A guest's tool calls need a review: by a person, the judge or a scoop.") and an epoch. Revoking (`guestRevoke(id)`) keeps a tombstone, bumps the epoch, withdraws the guest's messages still queued in the cone, and ends every guest link of the seat (`invalidatePrincipal`). An expired seat ends the same way at its expiry. Tombstones go 30 days after they end.
|
|
648
647
|
- **Joining.** The hub resolves the guest's token to the seat's id and label, and the owner page opens `owner.port({ guest: { id, label } })` and bridges it like a follower's. Before Chord sees the link, the worker checks that the seat exists, isn't revoked or expired, and has that label; otherwise it closes the port. The link's principal is `{ seat: 'guest', link, guest: { id, name, epoch } }`, and anything else the port asks for (`readOnly: false`, `pages`) is ignored.
|
|
649
648
|
- **What a guest gets.** Every contract served from the agent's host refuses a guest principal (`forbidden`) unless its factory is opened with `openToGuests`, so a contract added later is closed to guests until someone opens it. The only open one is `slicc.agent.guest`: its `guest` variant has the shared cone's transcript (its user, assistant, tool and compaction entries; `pi.live`; `pi.agent`'s model and thinking level; and only the guest's own queued messages) and the seat, plus `propose({ text, requestId })`. Everyone else gets its empty `none` variant.
|
|
@@ -667,7 +666,7 @@ The agent never holds a secret's value. Values live in the vault (`vault.sliccy.
|
|
|
667
666
|
- **The hold.** A vault that doesn't answer within 2 s reads as `waiting`. Nothing unscrubbed is appended: tool results, sends and licks wait in memory, model requests wait before they start, and command output held past 32 MiB kills the command with "output held: waiting for the vault". The state is the transcript's `vault` field (`{ port, needed, version, locked, held }`), and remote `watch` streams get a `notice` "waiting for the vault" and one when it answers again.
|
|
668
667
|
- **In spectrum.** The agent port's `hold()` is `{ reason: 'locked', held }` while the vault needs a passkey, `{ reason: 'waiting', held }` while scrubbing is needed and the port isn't `ready`, and `null` otherwise, with a `hold` event on each change (and `null` when it clears); spectrum (≥ 1.62.0) shows it above the composer, and older spectrum ignores it. While a hold is up, the worker's active cone is busy (`working` when it isn't running), so the composer steers and queues; a send made during the hold waits in the tab, shown in that cone's queue, and goes to the worker once the hold clears; removing it before then means it's never sent. `/secrets` entries (`slicc.secrets`) show as a "Secrets listed" notice.
|
|
669
668
|
- **The 3.x store is wiped.** 3.x kept model and MCP keys in the IndexedDB database `slicc-agent-credentials`; 4.x doesn't migrate them. At start, before any model call, the worker reads only that database's record keys (never decrypting), deletes it, and keeps the accounts it found (`adobe` as Adobe, `amazon-bedrock` as Bedrock, `mcp:<server>|…` as the server, anything else by its providerId) in the session document `slicc.keys-moved`. A missing database, or no `indexedDB`, does nothing. The worker waits up to 3 s for the delete and claims the keys moved only once it succeeds. A delete blocked by an open 3.x tab shows no notice yet: if it succeeds later in the session (the tab closes) its accounts are added then, and otherwise the next start tries again. A delete that fails reports nothing. Once the vault's records are read, the accounts still without a record are the settings state's `moved`, and the spectrum adapter's `notices` port shows one notice, with model accounts first and MCP servers grouped after them: "Your keys moved to seven's vault. Add them again in Settings › Accounts: Adobe, Bedrock; MCP servers: github, jira." (or "…, and the MCP server github" for one). Dismissing it calls `AgentSettings.dismissMoved`, which marks the document, so it stays dismissed across reloads. An account without a record reads not connected. A model call that finds no credential ("Provider is not configured", "No API key") leads with "Adobe isn't connected." or "Bedrock isn't connected.", with "Connect it in Settings › Accounts." underneath instead of the raw error, and opens settings, and a send whose run finds no model because its account isn't connected (Adobe lists models only once signed in) shows the same error. "Your Adobe session has expired." is kept for a 401 from a token that exists. The settings state's `labels` names every model of a provider without a record from the agent's catalogue ("Claude Haiku 4.5 (US) on Bedrock"), and the adapter puts that name in the header of a reply whose model isn't in the picker, instead of the raw id.
|
|
670
|
-
- **For bios:** the agent's `notices` (keys moved
|
|
669
|
+
- **For bios:** the agent's `notices` (keys moved) would replace bios's own port in `{ ...bios, ...createAgentModel(connection) }`, so pass that port in instead, as `createAgentModel(connection, { notices: biosPort })`. The returned port lists bios's notices and then the agent's, sends `act` and `dismiss` to whichever port listed the id (never dismissing one with `dismissible: false`), and passes on both ports' `notices` events. Without the option, it lists only the agent's.
|
|
671
670
|
- **Tests.** The worker never compiles values: `src/` takes only `import type { Hit }` from [`@ai-ecoverse/slicc-scrub`](https://www.npmjs.com/package/@ai-ecoverse/slicc-scrub), the vault's scrubber, and the package is a devDependency. The fake vault the tests use scrubs with that package, and its `vectors.json` (every form, line-wrapped base64 and hex included) runs through each scrub point and each cut. A suite-wide check asserts that no captured model request, entry, slot or memory file holds any form of a seeded value.
|
|
672
671
|
|
|
673
672
|
## The kernel
|
package/dist/client.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
createHost
|
|
3
|
-
isChordError
|
|
2
|
+
createHost
|
|
4
3
|
} from "@earendil-works/chord";
|
|
5
4
|
import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context";
|
|
6
|
-
import { mismatched } from "./mismatch.js";
|
|
7
5
|
import { controlAnswer, pageAnswer, remoteAnswer, settingsAnswer } from "./readonly.js";
|
|
8
6
|
import {
|
|
9
7
|
AgentControl,
|
|
@@ -18,7 +16,7 @@ import {
|
|
|
18
16
|
TRANSCRIPT_STATES
|
|
19
17
|
} from "./services.js";
|
|
20
18
|
import { AGENT_HOST, bound, kept, replicated } from "./serving.js";
|
|
21
|
-
import {
|
|
19
|
+
import { PortLink } from "./wire.js";
|
|
22
20
|
function lasting(state) {
|
|
23
21
|
let last;
|
|
24
22
|
let frozen = false;
|
|
@@ -52,18 +50,13 @@ function lastingSettings(settings, hold) {
|
|
|
52
50
|
dismissMoved: (context) => settings.dismissMoved(context)
|
|
53
51
|
};
|
|
54
52
|
}
|
|
55
|
-
const MISMATCHES = /* @__PURE__ */ new Set(["contract_mismatch", "upgrade_required"]);
|
|
56
53
|
const ended = (link) => link.ended.then((reason) => {
|
|
57
54
|
throw reason ?? new Error("the agent closed the link");
|
|
58
55
|
});
|
|
59
56
|
async function connectAgent(endpoint, options = {}) {
|
|
60
57
|
const context = options.context ?? BACKGROUND_CONTEXT;
|
|
61
58
|
const link = new PortLink(endpoint);
|
|
62
|
-
const
|
|
63
|
-
if (peer.protocol !== LINK_PROTOCOL) {
|
|
64
|
-
link.close("link protocol mismatch");
|
|
65
|
-
return mismatched(peer.serverId, peer.protocol);
|
|
66
|
-
}
|
|
59
|
+
const serverId = await link.hello;
|
|
67
60
|
const host = createHost({ name: `follower:${crypto.randomUUID()}`, kind: "client" });
|
|
68
61
|
host.connect(link);
|
|
69
62
|
const get = (contract) => host.get(contract, {}, { at: AGENT_HOST });
|
|
@@ -83,8 +76,6 @@ async function connectAgent(endpoint, options = {}) {
|
|
|
83
76
|
} catch (error) {
|
|
84
77
|
release();
|
|
85
78
|
link.close("handshake failed");
|
|
86
|
-
if (isChordError(error) && MISMATCHES.has(error.code))
|
|
87
|
-
return mismatched(peer.serverId, peer.protocol);
|
|
88
79
|
throw error;
|
|
89
80
|
}
|
|
90
81
|
const root = (run, rootOptions) => host.root(run, rootOptions);
|
|
@@ -121,7 +112,7 @@ async function connectAgent(endpoint, options = {}) {
|
|
|
121
112
|
return reason;
|
|
122
113
|
});
|
|
123
114
|
return {
|
|
124
|
-
serverId
|
|
115
|
+
serverId,
|
|
125
116
|
readOnly: controlHandle.kind === "view",
|
|
126
117
|
control,
|
|
127
118
|
transcript: hold(state("state")),
|
package/dist/client.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/client.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type Context,\n createHost,\n
|
|
5
|
-
"mappings": "AAAA;AAAA,EAEE;AAAA,
|
|
4
|
+
"sourcesContent": ["import {\n type Context,\n createHost,\n type Readable,\n type ReplicatedState,\n} from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { ConversationView } from '@earendil-works/pi-durable';\nimport type { Approval } from './approvals/record.ts';\nimport type { ChangesView } from './changes/git.ts';\nimport type { FrozenCone } from './freezer/index.ts';\nimport type { GuestSeat } from './guests/seats.ts';\nimport type { MemoryEntry, MemoryScope } from './memory/format.ts';\nimport { controlAnswer, pageAnswer, remoteAnswer, settingsAnswer } from './readonly.ts';\nimport type { AgentRemote } from './remote/host.ts';\nimport type { AgentPages } from './remote/pages.ts';\nimport type { VaultState } from './secrets/vault.ts';\nimport {\n AgentControl,\n AgentPagesService,\n AgentRemoteService,\n AgentSettings,\n type AgentsSummary,\n AgentTranscript,\n CONTROL_METHODS,\n type Command,\n type Delivered,\n type GuestProposal,\n type GuestShown,\n type MonitorFeed,\n PAGE_METHODS,\n type PrivateRevision,\n REMOTE_METHODS,\n SETTINGS_METHODS,\n type SendMode,\n type SettingsState,\n TRANSCRIPT_STATES,\n} from './services.ts';\nimport { AGENT_HOST, bound, kept, type Remote, type Root, replicated } from './serving.ts';\nimport type { Sprinkle } from './sprinkles/kind.ts';\nimport { type PortEndpoint, PortLink } from './wire.ts';\n\nexport interface AgentConnection {\n readonly serverId: string;\n readonly control: AgentControl;\n readonly transcript: ReplicatedState<ConversationView>;\n readonly deliveries: ReplicatedState<Record<string, Delivered>>;\n readonly agents?: ReplicatedState<AgentsSummary>;\n readonly views?: ReplicatedState<Record<string, ConversationView>>;\n readonly commands?: ReplicatedState<Command[]>;\n readonly privateRevision?: ReplicatedState<PrivateRevision>;\n readonly sprinkles?: ReplicatedState<Sprinkle[]>;\n readonly memories?: ReplicatedState<MemoryEntry[]>;\n readonly memoryScopes?: ReplicatedState<MemoryScope[]>;\n readonly frozen?: ReplicatedState<FrozenCone[]>;\n readonly changes?: ReplicatedState<ChangesView>;\n readonly monitor?: ReplicatedState<MonitorFeed>;\n readonly vault?: ReplicatedState<VaultState>;\n readonly labels?: ReplicatedState<Record<string, string>>;\n readonly guests?: ReplicatedState<GuestSeat[]>;\n readonly viewOnly?: boolean;\n readonly guest?: GuestShown;\n readonly proposals?: ReplicatedState<GuestProposal[]>;\n readonly owner?: boolean;\n readonly approvals?: ReplicatedState<Approval[]>;\n readonly settings: AgentSettings;\n readonly remote?: AgentRemote;\n readonly pages?: AgentPages;\n readonly closed: Promise<Error | undefined>;\n readonly readOnly?: boolean;\n prompt(text: string, whenBusy?: SendMode): Promise<string>;\n webhook(\n name: string,\n delivery: { id?: string | null; headers?: Record<string, string>; body: string }\n ): Promise<{ delivered: boolean }>;\n close(): Promise<void>;\n}\n\nexport interface Lasting<T> {\n readonly state: ReplicatedState<T>;\n freeze(): void;\n}\n\nexport function lasting<T>(state: ReplicatedState<T>): Lasting<T> {\n let last: T | undefined;\n let frozen = false;\n const read = () => {\n if (frozen) return last;\n try {\n last = state.value;\n } catch {}\n return last;\n };\n return {\n state: {\n get value() {\n return read();\n },\n subscribe: (listener) => (frozen ? () => undefined : state.subscribe(listener)),\n },\n freeze() {\n read();\n frozen = true;\n },\n };\n}\n\nfunction lastingSettings(\n settings: AgentSettings,\n hold: <T>(state: ReplicatedState<T>) => ReplicatedState<T>\n): AgentSettings {\n return {\n state: hold(settings.state),\n connect: (providerId, secret, fields, context) =>\n settings.connect(providerId, secret, fields, context),\n disconnect: (providerId, context) => settings.disconnect(providerId, context),\n signIn: (providerId, context) => settings.signIn(providerId, context),\n dismissMoved: (context) => settings.dismissMoved(context),\n };\n}\n\nconst ended = (link: PortLink): Promise<never> =>\n link.ended.then((reason) => {\n throw reason ?? new Error('the agent closed the link');\n });\n\nexport async function connectAgent(\n endpoint: PortEndpoint,\n options: { context?: Context } = {}\n): Promise<AgentConnection> {\n const context = options.context ?? BACKGROUND_CONTEXT;\n const link = new PortLink(endpoint);\n const serverId = await link.hello;\n const host = createHost({ name: `follower:${crypto.randomUUID()}`, kind: 'client' });\n host.connect(link);\n const get = (contract: Parameters<typeof host.get>[0]) =>\n host.get(contract, {}, { at: AGENT_HOST }) as unknown as Remote;\n const handles = [\n AgentControl,\n AgentTranscript,\n AgentSettings,\n AgentRemoteService,\n AgentPagesService,\n ].map(get);\n const [controlHandle, transcriptHandle, settingsHandle, remoteHandle, pagesHandle] = handles as [\n Remote,\n Remote,\n Remote,\n Remote,\n Remote,\n ];\n const release = () => {\n for (const handle of handles) handle.release();\n };\n try {\n await Promise.race([Promise.all(handles.map((handle) => handle.ready)), ended(link)]);\n } catch (error) {\n release();\n link.close('handshake failed');\n throw error;\n }\n const root: Root = (run, rootOptions) => host.root(run, rootOptions);\n const control = bound<AgentControl>(controlHandle, root, CONTROL_METHODS, controlAnswer);\n const members = Object.fromEntries(\n TRANSCRIPT_STATES.map((name) => [name, transcriptHandle[name] as Readable<unknown>])\n ) as Record<(typeof TRANSCRIPT_STATES)[number], Readable<unknown>>;\n const settingsState = settingsHandle.state as Readable<unknown>;\n const keeping = [...Object.values(members), settingsState].map(kept);\n await Promise.race([Promise.all(keeping.map((keep) => keep.ready)), ended(link)]);\n const settings: AgentSettings = {\n ...bound<Omit<AgentSettings, 'state'>>(settingsHandle, root, SETTINGS_METHODS, settingsAnswer),\n state: replicated(settingsState as Readable<SettingsState | undefined>),\n };\n const remote = bound<AgentRemote>(remoteHandle, root, REMOTE_METHODS, remoteAnswer);\n const pages = bound<AgentPages>(pagesHandle, root, PAGE_METHODS, pageAnswer);\n const state = <K extends keyof typeof members>(name: K) =>\n replicated(members[name] as Readable<never>);\n const held: Lasting<unknown>[] = [];\n const hold = <T>(state: ReplicatedState<T>): ReplicatedState<T> => {\n const kept = lasting(state);\n held.push(kept as Lasting<unknown>);\n return kept.state;\n };\n let open = true;\n const finish = () => {\n if (!open) return;\n open = false;\n for (const kept of held) kept.freeze();\n for (const keep of keeping) keep.stop();\n release();\n };\n const closed = link.ended.then((reason) => {\n finish();\n return reason;\n });\n return {\n serverId,\n readOnly: controlHandle.kind === 'view',\n control,\n transcript: hold<ConversationView>(state('state')),\n deliveries: hold<Record<string, Delivered>>(state('deliveries')),\n agents: hold<AgentsSummary>(state('agents')),\n views: hold<Record<string, ConversationView>>(state('views')),\n commands: hold<Command[]>(state('commands')),\n privateRevision: hold<PrivateRevision>(state('privateRevision')),\n sprinkles: hold<Sprinkle[]>(state('sprinkles')),\n memories: hold<MemoryEntry[]>(state('memories')),\n memoryScopes: hold<MemoryScope[]>(state('memoryScopes')),\n frozen: hold<FrozenCone[]>(state('frozen')),\n changes: hold<ChangesView>(state('changes')),\n monitor: hold<MonitorFeed>(state('monitor')),\n vault: hold<VaultState>(state('vault')),\n labels: hold<Record<string, string>>(state('labels')),\n guests: hold<GuestSeat[]>(state('guests')),\n viewOnly: controlHandle.kind === 'view',\n owner: pagesHandle.kind === 'pages',\n approvals: hold<Approval[]>(state('approvals')),\n settings: lastingSettings(settings, hold),\n remote,\n pages,\n closed,\n webhook(name, delivery) {\n return control.webhook(\n name,\n { id: delivery.id ?? null, headers: delivery.headers ?? {}, body: delivery.body },\n context\n );\n },\n async prompt(text, whenBusy = 'followUp') {\n const sent = await control.send({ text, whenBusy, requestId: null }, context);\n if (!sent.accepted) throw new Error(`${sent.error.code}: ${sent.error.message}`);\n const settled = await control.wait(sent.submissionId, context);\n if (settled.status !== 'done') throw new Error(`unanswered: ${settled.reason}`);\n return settled.text;\n },\n async close() {\n finish();\n link.close('closed');\n await closed;\n await host.close();\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["state", "kept"]
|
|
7
7
|
}
|
package/dist/guests/client.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { createHost, isChordError, replicatedState } from "@earendil-works/chord";
|
|
2
2
|
import { lasting } from "../client.js";
|
|
3
|
-
import { mismatched } from "../mismatch.js";
|
|
4
3
|
import {
|
|
5
4
|
AgentGuestService,
|
|
6
5
|
CONTROL_METHODS
|
|
7
6
|
} from "../services.js";
|
|
8
7
|
import { AGENT_HOST, kept, plain, replicated } from "../serving.js";
|
|
9
|
-
import {
|
|
10
|
-
const MISMATCHES = /* @__PURE__ */ new Set(["contract_mismatch", "upgrade_required"]);
|
|
8
|
+
import { PortLink } from "../wire.js";
|
|
11
9
|
const GUEST_ONLY = "a guest can only watch and send messages";
|
|
12
10
|
const SEAT_REFUSED = "This guest link isn't valid any more.";
|
|
13
11
|
const SAID = {
|
|
@@ -21,17 +19,12 @@ const proposedSentence = (reason) => SAID[reason] ?? "The message was not delive
|
|
|
21
19
|
const refusal = (message, code = "EACCES") => Object.assign(new Error(message), { code });
|
|
22
20
|
async function connectGuest(endpoint) {
|
|
23
21
|
const link = new PortLink(endpoint);
|
|
24
|
-
let
|
|
22
|
+
let serverId;
|
|
25
23
|
try {
|
|
26
|
-
|
|
24
|
+
serverId = await link.hello;
|
|
27
25
|
} catch {
|
|
28
26
|
throw refusal(SEAT_REFUSED);
|
|
29
27
|
}
|
|
30
|
-
const peer = greeted(hello);
|
|
31
|
-
if (peer.protocol !== LINK_PROTOCOL) {
|
|
32
|
-
link.close("link protocol mismatch");
|
|
33
|
-
return mismatched(peer.serverId, peer.protocol);
|
|
34
|
-
}
|
|
35
28
|
const host = createHost({ name: `guest:${crypto.randomUUID()}`, kind: "client" });
|
|
36
29
|
host.connect(link);
|
|
37
30
|
const handle = host.get(AgentGuestService, {}, { at: AGENT_HOST });
|
|
@@ -49,11 +42,6 @@ async function connectGuest(endpoint) {
|
|
|
49
42
|
})
|
|
50
43
|
]);
|
|
51
44
|
} catch (error) {
|
|
52
|
-
if (isChordError(error) && MISMATCHES.has(error.code)) {
|
|
53
|
-
handle.release();
|
|
54
|
-
link.close("handshake failed");
|
|
55
|
-
return mismatched(peer.serverId, peer.protocol);
|
|
56
|
-
}
|
|
57
45
|
return fail(isChordError(error) && error.code === "forbidden" ? refusal(SEAT_REFUSED) : error);
|
|
58
46
|
}
|
|
59
47
|
if (handle.kind !== "guest") return fail(refusal(SEAT_REFUSED));
|
|
@@ -116,7 +104,7 @@ async function connectGuest(endpoint) {
|
|
|
116
104
|
dismissMoved: refuse
|
|
117
105
|
};
|
|
118
106
|
return {
|
|
119
|
-
serverId
|
|
107
|
+
serverId,
|
|
120
108
|
guest,
|
|
121
109
|
control,
|
|
122
110
|
transcript: transcript.state,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/guests/client.ts"],
|
|
4
|
-
"sourcesContent": ["import { createHost, isChordError, type Readable, replicatedState } from '@earendil-works/chord';\nimport type { ConversationView } from '@earendil-works/pi-durable';\nimport { type AgentConnection, lasting } from '../client.ts';\nimport {
|
|
5
|
-
"mappings": "AAAA,SAAS,YAAY,cAA6B,uBAAuB;AAEzE,SAA+B,eAAe;AAC9C
|
|
4
|
+
"sourcesContent": ["import { createHost, isChordError, type Readable, replicatedState } from '@earendil-works/chord';\nimport type { ConversationView } from '@earendil-works/pi-durable';\nimport { type AgentConnection, lasting } from '../client.ts';\nimport {\n type AgentControl,\n AgentGuestService,\n type AgentSettings,\n CONTROL_METHODS,\n type GuestProposal,\n type GuestShown,\n type SendResponse,\n} from '../services.ts';\nimport { AGENT_HOST, kept, plain, type Remote, replicated } from '../serving.ts';\nimport { type PortEndpoint, PortLink } from '../wire.ts';\nimport type { Proposed, ProposeRequest } from './index.ts';\n\nexport const GUEST_ONLY = 'a guest can only watch and send messages';\nexport const SEAT_REFUSED = \"This guest link isn't valid any more.\";\n\nconst SAID: Record<string, string> = {\n revoked: 'This guest seat was revoked.',\n empty: 'There is nothing to send.',\n 'too-long': 'That message is too long for a guest seat.',\n gone: 'The cone this seat shares is gone.',\n unavailable: \"Messages from guests need a review, and this agent can't review them yet.\",\n};\n\nexport const proposedSentence = (reason: string): string =>\n SAID[reason] ?? 'The message was not delivered.';\n\nconst refusal = (message: string, code = 'EACCES') => Object.assign(new Error(message), { code });\n\nexport interface GuestConnection extends AgentConnection {\n readonly guest: GuestShown;\n propose(request: ProposeRequest): Promise<Proposed>;\n}\n\nexport async function connectGuest(endpoint: PortEndpoint): Promise<GuestConnection> {\n const link = new PortLink(endpoint);\n let serverId: string;\n try {\n serverId = await link.hello;\n } catch {\n throw refusal(SEAT_REFUSED);\n }\n const host = createHost({ name: `guest:${crypto.randomUUID()}`, kind: 'client' });\n host.connect(link);\n const handle = host.get(AgentGuestService, {}, { at: AGENT_HOST }) as unknown as Remote;\n const fail = async (error: unknown): Promise<never> => {\n handle.release();\n link.close('handshake failed');\n await host.close();\n throw error;\n };\n try {\n await Promise.race([\n handle.ready,\n link.ended.then(() => {\n throw refusal(SEAT_REFUSED);\n }),\n ]);\n } catch (error) {\n return fail(isChordError(error) && error.code === 'forbidden' ? refusal(SEAT_REFUSED) : error);\n }\n if (handle.kind !== 'guest') return fail(refusal(SEAT_REFUSED));\n const transcriptMember = handle.transcript as Readable<ConversationView | undefined>;\n const seatMember = handle.seat as Readable<GuestShown | undefined>;\n const proposalsMember = handle.proposals as Readable<GuestProposal[] | undefined>;\n const keeping = [transcriptMember, seatMember, proposalsMember].map(kept);\n await Promise.race([Promise.all(keeping.map((keep) => keep.ready)), link.ended]);\n const call = handle.propose as (args: unknown[], ctx: unknown) => Promise<Proposed>;\n const propose = async (request: ProposeRequest) => {\n try {\n return await host.root((ctx) => call([request], ctx), {});\n } catch (error) {\n throw plain(error);\n }\n };\n const guest = seatMember.value as GuestShown;\n const refuse = () => Promise.reject(refusal(GUEST_ONLY));\n const control = Object.fromEntries(\n CONTROL_METHODS.map((name) => [name, refuse])\n ) as unknown as AgentControl;\n control.send = async (request): Promise<SendResponse> => {\n if (request.attachments?.length)\n return {\n accepted: false,\n submissionId: null,\n error: { code: 'EACCES', message: \"A guest can't attach files.\" },\n };\n const proposed = await propose({ text: request.text, requestId: request.requestId });\n if (proposed.state === 'submitted')\n return { accepted: true, submissionId: proposed.submissionId, error: null };\n if (proposed.state === 'pending')\n return { accepted: true, submissionId: proposed.approval, error: null };\n return {\n accepted: false,\n submissionId: null,\n error: { code: 'EACCES', message: proposedSentence(proposed.reason) },\n };\n };\n const transcript = lasting(replicated(transcriptMember));\n const proposals = lasting(replicated(proposalsMember));\n let open = true;\n const finish = () => {\n if (!open) return;\n open = false;\n transcript.freeze();\n proposals.freeze();\n for (const keep of keeping) keep.stop();\n handle.release();\n };\n const closed = link.ended.then((reason) => {\n finish();\n return reason;\n });\n const settings: AgentSettings = {\n state: replicatedState({ models: [], accounts: [] }),\n connect: refuse,\n disconnect: refuse,\n signIn: refuse,\n dismissMoved: refuse,\n };\n return {\n serverId,\n guest,\n control,\n transcript: transcript.state,\n proposals: proposals.state,\n deliveries: replicatedState({}),\n agents: replicatedState({\n active: guest.agentId,\n agents: [\n { id: guest.agentId, name: guest.name, kind: 'cone' as const, parentId: null, role: null },\n ],\n }),\n settings,\n closed,\n propose,\n prompt: refuse,\n webhook: refuse,\n async close() {\n finish();\n link.close('closed');\n await closed;\n await host.close();\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/index.js
CHANGED
|
@@ -95,7 +95,7 @@ import {
|
|
|
95
95
|
} from "./sqlite.js";
|
|
96
96
|
import { systemSection } from "./system.js";
|
|
97
97
|
import { UPLOADS, upload } from "./uploads.js";
|
|
98
|
-
import {
|
|
98
|
+
import { PortLink } from "./wire.js";
|
|
99
99
|
import {
|
|
100
100
|
kernelPort,
|
|
101
101
|
kernelPorts,
|
|
@@ -125,7 +125,6 @@ export {
|
|
|
125
125
|
JUDGE_KIND,
|
|
126
126
|
JUDGE_MODEL,
|
|
127
127
|
JUDGE_QUESTIONS,
|
|
128
|
-
LINK_PROTOCOL,
|
|
129
128
|
POLICY_FILE,
|
|
130
129
|
PREFERRED_MODELS,
|
|
131
130
|
PortLink,
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["export {\n ADOBE,\n ADOBE_PROXY,\n type AdobeConfig,\n type AdobeModelInfo,\n adobeClassifiers,\n adobeConfig,\n adobeIdentity,\n adobeModel,\n adobeProvider,\n adobeUsage,\n type Budget,\n SESSION_HEADER,\n VERSION_HEADER,\n withAdobeIdentity,\n} from './adobe.ts';\nexport { type Agent, type AgentOptions, answerText, openAgent } from './agent.ts';\nexport {\n APPROVAL_MS,\n type Approval,\n type ApprovalAnswer,\n type ApprovalDecided,\n type ApprovalDraft,\n type ApprovalJudge,\n type ApprovalKind,\n type ApprovalRequester,\n type ApprovalState,\n type Approvals,\n ApprovalsDoc,\n type ApprovalTier,\n type ApprovalVerdict,\n approvalJudge,\n attachApprovals,\n DEFAULT_POLICY,\n type DecidedBy,\n JUDGE_ALLOW,\n JUDGE_DENY,\n JUDGE_KIND,\n JUDGE_MODEL,\n JUDGE_QUESTIONS,\n type Judgement,\n judgeModelOf,\n judgeSpender,\n judgeState,\n type OwnerIntent,\n ownerIntent,\n POLICY_FILE,\n REASONS,\n seedPolicy,\n VERDICT_REASONS,\n verdictOf,\n verdictRecorder,\n} from './approvals/index.ts';\nexport {\n FILE_LIMIT,\n IMAGE_LIMIT,\n type SendAttachment,\n type ShownAttachment,\n splitUser,\n TOTAL_LIMIT,\n userParts,\n} from './attachments.ts';\nexport { type AgentConnection, connectAgent } from './client.ts';\nexport { createAgentControl } from './control.ts';\nexport {\n connectGuest,\n GUEST_ONLY,\n type GuestConnection,\n SEAT_REFUSED,\n} from './guests/client.ts';\nexport type { GuestOpened, Proposed, ProposeRequest } from './guests/index.ts';\nexport type { GuestDraft, GuestGate, GuestGates, GuestSeat } from './guests/seats.ts';\nexport { type AgentHost, type ConnectOptions, hostAgent } from './host.ts';\nexport type {\n KernelClient,\n KernelFs,\n KernelProcess,\n KernelStat,\n SpawnOptions,\n} from './kernel/client.ts';\nexport { HOME, type KernelEnvOptions, kernelEnvironment, SliccKernelEnv } from './kernel/env.ts';\nexport {\n adminOver,\n type KernelAdmin,\n type KernelGroup,\n type KernelGroups,\n type KernelUser,\n type KernelUsers,\n serveAdmin,\n type UserClient,\n type UserClients,\n type UserConnect,\n type UserSpec,\n userClients,\n} from './kernel/users.ts';\nexport {\n type AgentWorkerOptions,\n type AgentWorkerScope,\n type KernelAttach,\n runAgentWorker,\n} from './main.ts';\nexport {\n type Loopback,\n type Transport,\n type TransportResponse,\n transportFetch,\n} from './net.ts';\nexport {\n AGENT_LOCK,\n type AgentOwner,\n type AgentWorker,\n type KernelSource,\n type OwnerOptions,\n startAgent,\n} from './owner.ts';\nexport { SliccPrompt, sliccPrompt } from './prompt.ts';\nexport {\n type AgentPages,\n createPages,\n type PageBatch,\n type PageCaller,\n type PageRequest,\n type PageResult,\n type Pages,\n type PagesOpened,\n type PageTab,\n} from './remote/pages.ts';\nexport {\n type AccountState,\n AgentControl,\n AgentPagesService,\n AgentSettings,\n type AgentSettingsChange,\n AgentTranscript,\n type BudgetState,\n type ModelChoice,\n type OperationError,\n type PromptResult,\n type SendMode,\n type SendRequest,\n type SendResponse,\n type SettingsState,\n type SignIn,\n} from './services.ts';\nexport {\n BEDROCK,\n createAgentSettings,\n createSliccModels,\n DEFAULT_MODEL,\n DEFAULT_REGIONS,\n PREFERRED_MODELS,\n preferredModel,\n resolveDefaultModel,\n sliccProviders,\n withDefaultRegions,\n} from './settings.ts';\nexport {\n AGENT_DIRECTORY,\n type OpfsSqliteOptions,\n openMemorySqliteStorage,\n openOpfsSqliteStorage,\n WasmSqliteDatabase,\n} from './sqlite.ts';\nexport { type SystemFacts, systemSection } from './system.ts';\nexport { UPLOADS, type Uploads, upload } from './uploads.ts';\nexport {
|
|
5
|
-
"mappings": "AAAA;AAAA,EACE;AAAA,EACA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAwC,YAAY,iBAAiB;AACrE;AAAA,EACE;AAAA,EAUA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAA+B,oBAAoB;AACnD,SAAS,0BAA0B;AACnC;AAAA,EACE;AAAA,EACA;AAAA,EAEA;AAAA,OACK;AAGP,SAA8C,iBAAiB;AAQ/D,SAAS,MAA6B,mBAAmB,sBAAsB;AAC/E;AAAA,EACE;AAAA,EAMA;AAAA,EAKA;AAAA,OACK;AACP;AAAA,EAIE;AAAA,OACK;AACP;AAAA,EAIE;AAAA,OACK;AACP;AAAA,EACE;AAAA,EAKA;AAAA,OACK;AACP,SAAS,aAAa,mBAAmB;AACzC;AAAA,EAEE;AAAA,OAQK;AACP;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,OAUK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAA2B,qBAAqB;AAChD,SAAS,SAAuB,cAAc;AAC9C,
|
|
4
|
+
"sourcesContent": ["export {\n ADOBE,\n ADOBE_PROXY,\n type AdobeConfig,\n type AdobeModelInfo,\n adobeClassifiers,\n adobeConfig,\n adobeIdentity,\n adobeModel,\n adobeProvider,\n adobeUsage,\n type Budget,\n SESSION_HEADER,\n VERSION_HEADER,\n withAdobeIdentity,\n} from './adobe.ts';\nexport { type Agent, type AgentOptions, answerText, openAgent } from './agent.ts';\nexport {\n APPROVAL_MS,\n type Approval,\n type ApprovalAnswer,\n type ApprovalDecided,\n type ApprovalDraft,\n type ApprovalJudge,\n type ApprovalKind,\n type ApprovalRequester,\n type ApprovalState,\n type Approvals,\n ApprovalsDoc,\n type ApprovalTier,\n type ApprovalVerdict,\n approvalJudge,\n attachApprovals,\n DEFAULT_POLICY,\n type DecidedBy,\n JUDGE_ALLOW,\n JUDGE_DENY,\n JUDGE_KIND,\n JUDGE_MODEL,\n JUDGE_QUESTIONS,\n type Judgement,\n judgeModelOf,\n judgeSpender,\n judgeState,\n type OwnerIntent,\n ownerIntent,\n POLICY_FILE,\n REASONS,\n seedPolicy,\n VERDICT_REASONS,\n verdictOf,\n verdictRecorder,\n} from './approvals/index.ts';\nexport {\n FILE_LIMIT,\n IMAGE_LIMIT,\n type SendAttachment,\n type ShownAttachment,\n splitUser,\n TOTAL_LIMIT,\n userParts,\n} from './attachments.ts';\nexport { type AgentConnection, connectAgent } from './client.ts';\nexport { createAgentControl } from './control.ts';\nexport {\n connectGuest,\n GUEST_ONLY,\n type GuestConnection,\n SEAT_REFUSED,\n} from './guests/client.ts';\nexport type { GuestOpened, Proposed, ProposeRequest } from './guests/index.ts';\nexport type { GuestDraft, GuestGate, GuestGates, GuestSeat } from './guests/seats.ts';\nexport { type AgentHost, type ConnectOptions, hostAgent } from './host.ts';\nexport type {\n KernelClient,\n KernelFs,\n KernelProcess,\n KernelStat,\n SpawnOptions,\n} from './kernel/client.ts';\nexport { HOME, type KernelEnvOptions, kernelEnvironment, SliccKernelEnv } from './kernel/env.ts';\nexport {\n adminOver,\n type KernelAdmin,\n type KernelGroup,\n type KernelGroups,\n type KernelUser,\n type KernelUsers,\n serveAdmin,\n type UserClient,\n type UserClients,\n type UserConnect,\n type UserSpec,\n userClients,\n} from './kernel/users.ts';\nexport {\n type AgentWorkerOptions,\n type AgentWorkerScope,\n type KernelAttach,\n runAgentWorker,\n} from './main.ts';\nexport {\n type Loopback,\n type Transport,\n type TransportResponse,\n transportFetch,\n} from './net.ts';\nexport {\n AGENT_LOCK,\n type AgentOwner,\n type AgentWorker,\n type KernelSource,\n type OwnerOptions,\n startAgent,\n} from './owner.ts';\nexport { SliccPrompt, sliccPrompt } from './prompt.ts';\nexport {\n type AgentPages,\n createPages,\n type PageBatch,\n type PageCaller,\n type PageRequest,\n type PageResult,\n type Pages,\n type PagesOpened,\n type PageTab,\n} from './remote/pages.ts';\nexport {\n type AccountState,\n AgentControl,\n AgentPagesService,\n AgentSettings,\n type AgentSettingsChange,\n AgentTranscript,\n type BudgetState,\n type ModelChoice,\n type OperationError,\n type PromptResult,\n type SendMode,\n type SendRequest,\n type SendResponse,\n type SettingsState,\n type SignIn,\n} from './services.ts';\nexport {\n BEDROCK,\n createAgentSettings,\n createSliccModels,\n DEFAULT_MODEL,\n DEFAULT_REGIONS,\n PREFERRED_MODELS,\n preferredModel,\n resolveDefaultModel,\n sliccProviders,\n withDefaultRegions,\n} from './settings.ts';\nexport {\n AGENT_DIRECTORY,\n type OpfsSqliteOptions,\n openMemorySqliteStorage,\n openOpfsSqliteStorage,\n WasmSqliteDatabase,\n} from './sqlite.ts';\nexport { type SystemFacts, systemSection } from './system.ts';\nexport { UPLOADS, type Uploads, upload } from './uploads.ts';\nexport { type PortEndpoint, PortLink } from './wire.ts';\nexport {\n type KernelPorts,\n kernelPort,\n kernelPorts,\n serveConnections,\n type WorkerScope,\n} from './worker.ts';\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA,EACE;AAAA,EACA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAwC,YAAY,iBAAiB;AACrE;AAAA,EACE;AAAA,EAUA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAA+B,oBAAoB;AACnD,SAAS,0BAA0B;AACnC;AAAA,EACE;AAAA,EACA;AAAA,EAEA;AAAA,OACK;AAGP,SAA8C,iBAAiB;AAQ/D,SAAS,MAA6B,mBAAmB,sBAAsB;AAC/E;AAAA,EACE;AAAA,EAMA;AAAA,EAKA;AAAA,OACK;AACP;AAAA,EAIE;AAAA,OACK;AACP;AAAA,EAIE;AAAA,OACK;AACP;AAAA,EACE;AAAA,EAKA;AAAA,OACK;AACP,SAAS,aAAa,mBAAmB;AACzC;AAAA,EAEE;AAAA,OAQK;AACP;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,OAUK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAA2B,qBAAqB;AAChD,SAAS,SAAuB,cAAc;AAC9C,SAA4B,gBAAgB;AAC5C;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -33,7 +33,6 @@ function answers(messages) {
|
|
|
33
33
|
function slashCommand({ kind, ...command }) {
|
|
34
34
|
return kind === "action" ? command : { ...command, kind };
|
|
35
35
|
}
|
|
36
|
-
const WATCH_ONLY = "Watch only.";
|
|
37
36
|
function sameHold(a, b) {
|
|
38
37
|
return a === b || a !== null && b !== null && a.reason === b.reason && a.held === b.held;
|
|
39
38
|
}
|
|
@@ -203,9 +202,6 @@ class AgentAdapter extends Emitter {
|
|
|
203
202
|
hold() {
|
|
204
203
|
return vaultHold(this.#connection.vault?.value);
|
|
205
204
|
}
|
|
206
|
-
readOnly() {
|
|
207
|
-
return this.#connection.mismatch ? WATCH_ONLY : null;
|
|
208
|
-
}
|
|
209
205
|
list() {
|
|
210
206
|
const rows = this.#connection.frozen?.value ?? [];
|
|
211
207
|
return this.#summary().map((summary) => {
|
|
@@ -585,7 +581,6 @@ class AgentAdapter extends Emitter {
|
|
|
585
581
|
export {
|
|
586
582
|
AgentAdapter,
|
|
587
583
|
CONE,
|
|
588
|
-
WATCH_ONLY,
|
|
589
584
|
slashCommand
|
|
590
585
|
};
|
|
591
586
|
//# sourceMappingURL=agent-port.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/spectrum/agent-port.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n Agent,\n AgentEvents,\n AgentPort,\n AgentStatus,\n FrozenCone,\n Message,\n Outgoing,\n SlashCommand,\n SystemMessage,\n Thinking,\n UserMessage,\n} from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { ConversationView } from '@earendil-works/pi-durable';\nimport type { AgentConnection } from '../client.ts';\nimport { contextRatio, contextTokens } from '../context.ts';\nimport { shrink } from '../images/fit.ts';\nimport { entryLick } from '../licks/state.ts';\nimport { type VaultHold, vaultHold } from '../secrets/view.ts';\nimport type { AgentSettingsChange, AgentSummary, Command } from '../services.ts';\nimport { shownLabel } from '../titles/shown.ts';\nimport { attempt } from './attempt.ts';\nimport { Emitter } from './emitter.ts';\nimport { CONNECT_IT, isBusy, providerName, queued, toMessages } from './messages.ts';\nimport { readUrl, sendAttachments } from './outgoing.ts';\nimport { merged, proposalNotices, proposalQueue } from './proposals.ts';\n\nexport const CONE = 'cone';\n\nconst thinking: Record<string, Thinking> = {\n off: 'off',\n minimal: 'low',\n low: 'low',\n medium: 'medium',\n high: 'high',\n xhigh: 'high',\n max: 'high',\n};\n\ninterface AgentDoc {\n model?: { provider: string; modelId: string };\n thinkingLevel?: string;\n}\n\nfunction status(view: ConversationView | undefined, messages: readonly Message[]): AgentStatus {\n if (isBusy(view)) {\n const live = view?.docs['pi.live'] as { tools?: { status: string }[] } | undefined;\n return live?.tools?.some((slot) => slot.status === 'running') ? 'working' : 'thinking';\n }\n const last = messages.at(-1);\n return last?.role === 'assistant' && last.status === 'error' ? 'error' : 'idle';\n}\n\nfunction answers(messages: readonly Message[]): string[] {\n return messages\n .filter((message) => message.role === 'assistant' && message.status !== 'streaming')\n .map((message) => message.id);\n}\n\nexport function slashCommand({ kind, ...command }: Command): SlashCommand {\n return kind === 'action' ? command : { ...command, kind };\n}\n\nexport const WATCH_ONLY = 'Watch only.';\n\nexport type AgentHold = VaultHold;\n\nexport type AgentAdapterEvents = AgentEvents & { hold: AgentHold | null };\n\nfunction sameHold(a: AgentHold | null, b: AgentHold | null): boolean {\n return a === b || (a !== null && b !== null && a.reason === b.reason && a.held === b.held);\n}\n\ninterface Pending {\n agentId: string;\n message: UserMessage;\n dropped: boolean;\n release(): void;\n released: Promise<void>;\n}\n\nexport class AgentAdapter extends Emitter<AgentAdapterEvents> implements AgentPort {\n readonly #connection: AgentConnection;\n readonly #ready: Promise<void>;\n readonly #messages = new Map<string, Message[]>();\n #active: string | null = null;\n #creating = new Map<string, Promise<string | null>>();\n #hold: AgentHold | null = null;\n readonly #outbox = new Map<string, Pending>();\n readonly #notices = new Map<string, { at: number; message: SystemMessage }[]>();\n readonly #unread = new Map<string, number>();\n readonly #seen = new Map<string, Set<string>>();\n readonly #queuedAt = new Map<string, Map<string, { at: number; seen: boolean }>>();\n #opened: ReadonlySet<string> | null = null;\n readonly #agentCommandsCache = new Map<string, Command[]>();\n readonly #agentCommandsLoading = new Set<string>();\n #agentCommandsGeneration = 0;\n\n constructor(connection: AgentConnection) {\n super();\n this.#connection = connection;\n this.#hold = this.hold();\n connection.vault?.subscribe(() => {\n const next = this.hold();\n if (sameHold(next, this.#hold)) return;\n this.#hold = next;\n if (!next) for (const pending of this.#outbox.values()) pending.release();\n this.emit('hold', next);\n this.emit('agents', this.list());\n });\n connection.proposals?.subscribe(() => {\n const agentId = connection.guest?.agentId;\n if (agentId) this.emit('messages', agentId);\n });\n connection.frozen?.subscribe(() => {\n this.emit('frozen', this.frozen());\n this.emit('agents', this.list());\n });\n this.#ready = new Promise((resolve) => {\n connection.transcript.subscribe(() => {\n this.#refresh();\n resolve();\n });\n connection.deliveries.subscribe(() => this.#refresh());\n connection.views?.subscribe(() => this.#refresh());\n connection.agents?.subscribe(() => this.#refresh());\n });\n connection.settings?.state.subscribe(() => {\n this.emit('agents', this.list());\n this.#refresh();\n });\n const stale = () => {\n this.#agentCommandsGeneration += 1;\n this.#agentCommandsLoading.clear();\n this.#agentCommandsCache.clear();\n this.emit('agents', this.list());\n };\n connection.commands?.subscribe(stale);\n connection.privateRevision?.subscribe(stale);\n }\n\n #summary(): readonly AgentSummary[] {\n const agents = this.#connection.agents?.value?.agents;\n return agents?.length\n ? agents\n : [{ id: CONE, name: 'sliccy', kind: 'cone', parentId: null, role: null }];\n }\n\n #view(agentId: string = this.active()): ConversationView | undefined {\n const views = this.#connection.views?.value;\n const view = views?.[agentId];\n if (view) return view;\n const cone = this.#connection.agents?.value?.active ?? CONE;\n return agentId === cone ? this.#connection.transcript.value : undefined;\n }\n\n #refresh(): void {\n this.#active ??= this.#connection.agents?.value?.active ?? null;\n if (!this.#opened && (!this.#connection.agents || this.#connection.agents.value))\n this.#opened = new Set(this.#summary().map((summary) => summary.id));\n for (const summary of this.#summary()) this.#stamp(summary.id, this.#view(summary.id));\n this.emit('agents', this.list());\n let unread = false;\n for (const summary of this.#summary()) unread = this.#update(summary.id) || unread;\n for (const id of [...this.#messages.keys(), ...this.#notices.keys(), ...this.#seen.keys()])\n if (!this.#summary().some((summary) => summary.id === id)) {\n this.#messages.delete(id);\n this.#notices.delete(id);\n this.#seen.delete(id);\n this.#unread.delete(id);\n this.#queuedAt.delete(id);\n }\n if (unread) this.emit('agents', this.list());\n }\n\n #count(agentId: string, view: ConversationView, messages: readonly Message[]): boolean {\n const ids = answers(messages);\n const known = this.#seen.get(agentId);\n if (agentId === this.active() || (!known && (!this.#opened || this.#opened.has(agentId)))) {\n this.#seen.set(agentId, new Set(ids));\n return false;\n }\n const seen = known ?? new Set<string>();\n this.#seen.set(agentId, seen);\n const fresh = isBusy(view) ? [] : ids.filter((id) => !seen.has(id));\n if (!fresh.length) return false;\n for (const id of fresh) seen.add(id);\n this.#unread.set(agentId, (this.#unread.get(agentId) ?? 0) + fresh.length);\n return true;\n }\n\n notify(text: string, agentId: string = this.active()): void {\n this.#note(agentId, { kind: 'notice', text });\n }\n\n #note(agentId: string, shown: Pick<SystemMessage, 'kind' | 'text' | 'title' | 'action'>): void {\n const notes = this.#notices.get(agentId) ?? [];\n notes.push({\n at: this.#messages.get(agentId)?.length ?? 0,\n message: { id: `n${crypto.randomUUID()}`, role: 'system', ...shown, createdAt: Date.now() },\n });\n this.#notices.set(agentId, notes);\n this.emit('messages', agentId);\n }\n\n #unconnected(agentId: string, submissionId: string): void {\n const provider = this.list()\n .find((row) => row.id === agentId)\n ?.model.split('/')[0];\n const accounts = this.#connection.settings?.state.value?.accounts ?? [];\n const account = accounts.find((item) => item.id === provider);\n if (!account || account.status === 'connected') return;\n const title = `${providerName(account.id, account.provider)} isn't connected.`;\n this.#connection.control.wait(submissionId, BACKGROUND_CONTEXT).then(\n (settled) => {\n if (settled.status === 'unanswered' && settled.reason === 'no_model')\n this.#note(agentId, {\n kind: 'error',\n title,\n text: CONNECT_IT,\n action: 'settings',\n });\n },\n () => undefined\n );\n }\n\n #report(agentId: string): (text: string) => void {\n return (text) => this.notify(text, agentId);\n }\n\n #update(agentId: string): boolean {\n const view = this.#view(agentId);\n if (!view) return false;\n const before = this.#messages.get(agentId) ?? [];\n const after = this.#labelled(toMessages(view, this.#connection.deliveries.value));\n this.#messages.set(agentId, after);\n if (before.length !== after.length) this.emit('messages', agentId);\n else {\n const changed = after.filter(\n (message, index) => JSON.stringify(message) !== JSON.stringify(before[index])\n );\n if (changed.length === 1) this.emit('message', { agentId, message: changed[0] as Message });\n else if (changed.length > 1) this.emit('messages', agentId);\n }\n return this.#count(agentId, view, after);\n }\n\n #labelled(messages: Message[]): Message[] {\n const state = this.#connection.settings?.state.value;\n const labels = state?.labels ?? {};\n const known = new Set((state?.models ?? []).map((model) => model.id));\n return messages.map((message) =>\n message.role === 'assistant' &&\n message.model &&\n !known.has(message.model) &&\n labels[message.model]\n ? { ...message, model: labels[message.model] as string }\n : message\n );\n }\n\n ready(): Promise<void> {\n return this.#ready;\n }\n\n hold(): AgentHold | null {\n return vaultHold(this.#connection.vault?.value);\n }\n\n readOnly(): string | null {\n return this.#connection.mismatch ? WATCH_ONLY : null;\n }\n\n list(): readonly Agent[] {\n const rows = this.#connection.frozen?.value ?? [];\n return this.#summary().map((summary) => {\n const view = this.#view(summary.id);\n const doc = view?.docs['pi.agent'] as AgentDoc | undefined;\n const title = rows.find((row) => row.id === summary.id)?.title;\n const model = doc?.model ? `${doc.model.provider}/${doc.model.modelId}` : '';\n const models = this.#connection.settings?.state.value?.models ?? [];\n return {\n id: summary.id,\n name: summary.role ? `${summary.name} \u00B7 ${summary.role}` : summary.name,\n kind: summary.kind,\n parentId: summary.parentId,\n status: this.#status(summary.id, status(view, this.#messages.get(summary.id) ?? [])),\n model,\n contextFill: contextRatio(contextTokens(view), model, models) ?? 0,\n unread: this.#unread.get(summary.id) ?? 0,\n thinking: thinking[doc?.thinkingLevel ?? 'off'] ?? 'off',\n ...(title ? { title } : {}),\n };\n });\n }\n\n active(): string {\n const known = this.#summary();\n if (this.#active && this.#creating.has(this.#active)) return this.#active;\n if (this.#active && known.some((summary) => summary.id === this.#active)) return this.#active;\n return this.#connection.agents?.value?.active ?? CONE;\n }\n\n select(id: string): void {\n if (this.#creating.has(id)) {\n this.#active = id;\n this.emit('active', id);\n return;\n }\n const found = this.#summary().find((summary) => summary.id === id);\n if (!found) return;\n this.#active = id;\n this.#seen.set(id, new Set(answers(this.#messages.get(id) ?? [])));\n const read = this.#unread.delete(id);\n if (found.kind === 'cone')\n attempt(\n this.#connection.control.selectCone(id, BACKGROUND_CONTEXT),\n 'switch cones',\n this.#report(id)\n );\n this.emit('active', id);\n this.emit('messages', id);\n if (read) this.emit('agents', this.list());\n }\n\n messages(agentId: string = this.active()): readonly Message[] {\n const listed = this.#listed(agentId);\n const guest = this.#connection.guest;\n if (!guest || guest.agentId !== agentId) return listed;\n return merged(listed, proposalNotices(this.#connection.proposals?.value));\n }\n\n #listed(agentId: string): readonly Message[] {\n const shown = this.#messages.get(agentId) ?? [];\n const notes = this.#notices.get(agentId);\n if (!notes) return shown;\n const at = (index: number) => notes.filter((note) => note.at === index).map((n) => n.message);\n const late = notes.filter((note) => note.at >= shown.length).map((note) => note.message);\n return [...shown.flatMap((message, index) => [...at(index), message]), ...late];\n }\n\n async send(agentId: string, input: string | Outgoing): Promise<void> {\n const outgoing = typeof input === 'string' ? { text: input } : input;\n const attachments = outgoing.attachments?.length\n ? await sendAttachments(outgoing.attachments, readUrl, shrink, (ref) =>\n this.#connection.control.image(ref, BACKGROUND_CONTEXT)\n ).catch((error: Error) => {\n this.notify(error.message, agentId);\n return null;\n })\n : [];\n if (!attachments) return;\n const target = this.#creating.has(agentId) ? await this.#creating.get(agentId) : agentId;\n if (target === null) throw new Error('The scoop could not be created.');\n const pending = target && this.#held(target) ? this.#pending(target, outgoing) : undefined;\n if (pending) await pending.released;\n if (pending?.dropped) return this.#settle(pending);\n const at = Date.now();\n const sent = await this.#connection.control\n .send(\n {\n text: outgoing.text,\n whenBusy: outgoing.mode === 'queue' ? 'followUp' : 'steer',\n requestId: crypto.randomUUID(),\n agentId: target || null,\n ...(attachments.length ? { attachments } : {}),\n },\n BACKGROUND_CONTEXT\n )\n .finally(() => pending && this.#settle(pending));\n if (!sent.accepted) throw new Error(sent.error.message);\n this.#sent(target || agentId, `q${sent.submissionId}`, at);\n this.#unconnected(target || agentId, sent.submissionId);\n if (pending?.dropped)\n attempt(\n this.#connection.control.unqueue(pending.agentId, sent.submissionId, BACKGROUND_CONTEXT),\n 'remove queued messages',\n this.#report(pending.agentId)\n );\n }\n\n #stamps(agentId: string): Map<string, { at: number; seen: boolean }> {\n const stamps = this.#queuedAt.get(agentId) ?? new Map();\n this.#queuedAt.set(agentId, stamps);\n return stamps;\n }\n\n #sent(agentId: string, id: string, at: number): void {\n const stamps = this.#stamps(agentId);\n const known = stamps.get(id);\n stamps.set(id, { at: Math.min(at, known?.at ?? at), seen: known?.seen ?? false });\n }\n\n #stamp(agentId: string, view: ConversationView | undefined): void {\n const stamps = this.#stamps(agentId);\n const ids = new Set(queued(view).map((message) => message.id));\n const now = Date.now();\n for (const id of ids) stamps.set(id, { at: stamps.get(id)?.at ?? now, seen: true });\n for (const [id, stamp] of stamps)\n if (!ids.has(id) && (stamp.seen || (!ids.size && !isBusy(view)))) stamps.delete(id);\n }\n\n #pending(agentId: string, outgoing: Outgoing): Pending {\n const id = `p${crypto.randomUUID()}`;\n const message: UserMessage = {\n id,\n role: 'user',\n text: outgoing.text,\n createdAt: Date.now(),\n ...(outgoing.attachments?.length ? { attachments: [...outgoing.attachments] } : {}),\n queued: true,\n mode: outgoing.mode === 'queue' ? 'queue' : 'steer',\n };\n const { promise: released, resolve: release } = Promise.withResolvers<void>();\n const pending = { agentId, message, dropped: false, release, released };\n this.#outbox.set(id, pending);\n this.emit('messages', agentId);\n return pending;\n }\n\n #settle(pending: Pending): void {\n this.#outbox.delete(pending.message.id);\n this.emit('messages', pending.agentId);\n }\n\n async rewind(agentId: string, messageId: string): Promise<Outgoing | null> {\n const rewound = await this.#connection.control.rewindAgent(\n agentId,\n messageId,\n BACKGROUND_CONTEXT\n );\n if (!rewound.done) return null;\n return rewound.attachments?.length\n ? { text: rewound.text, attachments: rewound.attachments }\n : { text: rewound.text };\n }\n\n stop(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.stopAgent(agentId, BACKGROUND_CONTEXT),\n 'stop agents',\n this.#report(agentId)\n );\n }\n\n busy(agentId: string = this.active()): boolean {\n return isBusy(this.#view(agentId)) || this.#held(agentId);\n }\n\n #status(agentId: string, shown: AgentStatus): AgentStatus {\n return shown === 'idle' && this.#held(agentId) ? 'working' : shown;\n }\n\n #held(agentId: string): boolean {\n return this.#hold !== null && agentId === (this.#connection.agents?.value?.active ?? CONE);\n }\n\n queue(agentId: string = this.active()): readonly UserMessage[] {\n const pending = [...this.#outbox.values()]\n .filter((item) => item.agentId === agentId && !item.dropped)\n .map((item) => item.message);\n const stamps = this.#queuedAt.get(agentId);\n const at = (id: string) => stamps?.get(id)?.at ?? 0;\n const guest = this.#connection.guest;\n const proposed =\n guest && guest.agentId === agentId\n ? proposalQueue(this.#connection.proposals?.value, guest.label)\n : [];\n return [...queued(this.#view(agentId), at), ...proposed, ...pending];\n }\n\n unqueue(agentId: string, messageId: string): void {\n const pending = this.#outbox.get(messageId);\n if (pending) {\n pending.dropped = true;\n pending.release();\n this.emit('messages', pending.agentId);\n return;\n }\n attempt(\n this.#connection.control.unqueue(agentId, messageId.replace(/^q/, ''), BACKGROUND_CONTEXT),\n 'remove queued messages',\n this.#report(agentId)\n );\n }\n\n suggestion(): string | null {\n return null;\n }\n\n answer(): void {}\n\n resolveLick(agentId: string, messageId: string, state: 'confirmed' | 'dismissed'): void {\n const message = this.messages(agentId).find((candidate) => candidate.id === messageId);\n const entry = this.#view(agentId)?.entries.find(\n (candidate) => `e${candidate.id}` === messageId\n );\n const lick = message?.role === 'lick' && entry ? entryLick(entry) : undefined;\n if (lick)\n attempt(\n this.#connection.control.resolveAgentLick(agentId, lick.id, state, BACKGROUND_CONTEXT),\n 'answer licks',\n this.#report(agentId)\n );\n }\n\n compact(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.compactAgent(agentId, null, BACKGROUND_CONTEXT),\n 'compact conversations',\n this.#report(agentId)\n );\n }\n\n clear(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.newChat(agentId, BACKGROUND_CONTEXT),\n 'start new chats',\n this.#report(agentId)\n );\n }\n\n freeze(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.freeze(agentId, BACKGROUND_CONTEXT),\n 'freeze cones',\n this.#report(agentId)\n );\n }\n\n #configure(agentId: string, change: Partial<AgentSettingsChange>): void {\n attempt(\n this.#connection.control.configure(\n {\n model: change.model ?? null,\n thinkingLevel: change.thinkingLevel ?? null,\n agentId,\n },\n BACKGROUND_CONTEXT\n ),\n 'change agent settings',\n this.#report(agentId)\n );\n }\n\n setModel(agentId: string, model: string): void {\n const at = model.indexOf('/');\n if (at <= 0) return;\n this.#configure(agentId, {\n model: { provider: model.slice(0, at), modelId: model.slice(at + 1) },\n });\n }\n\n setThinking(agentId: string, level: Thinking): void {\n this.#configure(agentId, { thinkingLevel: level });\n }\n\n async older(): Promise<readonly Message[]> {\n return [];\n }\n\n #fetchCommands(agentId: string): void {\n if (this.#agentCommandsLoading.has(agentId)) return;\n if (typeof this.#connection.control.agentCommands !== 'function') return;\n this.#agentCommandsLoading.add(agentId);\n const generation = this.#agentCommandsGeneration;\n this.#connection.control\n .agentCommands(agentId, BACKGROUND_CONTEXT)\n .then((commands) => {\n if (generation !== this.#agentCommandsGeneration) return;\n this.#agentCommandsCache.set(agentId, commands);\n this.emit('agents', this.list());\n })\n .catch(() => undefined)\n .finally(() => {\n if (generation === this.#agentCommandsGeneration)\n this.#agentCommandsLoading.delete(agentId);\n });\n }\n\n commands(agentId: string = this.active()): readonly SlashCommand[] {\n const cached = this.#agentCommandsCache.get(agentId);\n if (cached) return cached.map(slashCommand);\n this.#fetchCommands(agentId);\n return (this.#connection.commands?.value ?? []).map(slashCommand);\n }\n\n createScoop(parentId: string, name: string): Agent {\n const provisional = `scoop:creating-${crypto.randomUUID()}`;\n const created = this.#connection.control.createScoop(parentId, name, BACKGROUND_CONTEXT).then(\n (result) => result.id,\n () => null\n );\n this.#creating.set(provisional, created);\n void created.then((id) => {\n if (this.#active !== provisional) return;\n this.#active = id ?? parentId;\n this.emit('active', this.#active);\n this.emit('messages', this.#active);\n });\n return {\n id: provisional,\n name,\n kind: 'scoop',\n parentId,\n status: 'idle',\n model: '',\n contextFill: 0,\n unread: 0,\n };\n }\n\n async drop(agentId: string): Promise<void> {\n const parent = this.#summary().find((summary) => summary.id === agentId)?.parentId ?? CONE;\n const dropped = await this.#connection.control.drop(agentId, BACKGROUND_CONTEXT);\n if (dropped.error !== null) throw new Error(dropped.error);\n if (this.#active === agentId) this.select(parent);\n }\n\n async createCone(name: string): Promise<Agent> {\n const created = await this.#connection.control.createCone(name, BACKGROUND_CONTEXT);\n if (created.error !== null) throw new Error(created.error);\n return {\n id: created.id,\n name: name.trim(),\n kind: 'cone',\n parentId: null,\n status: 'idle',\n model: '',\n contextFill: 0,\n unread: 0,\n };\n }\n\n async toolLabel(agentId: string, callIds: readonly string[]): Promise<string | null> {\n const shown = shownLabel(this.#connection.labels?.value, callIds);\n if (shown !== undefined) return shown;\n return this.#connection.control\n .toolLabel(agentId, [...callIds], BACKGROUND_CONTEXT)\n .catch(() => null);\n }\n\n frozen(): readonly FrozenCone[] {\n return (this.#connection.frozen?.value ?? []).map(\n ({ id, name, title, model, messages, frozenAt, kind, live, thawedAs }) => ({\n id,\n name,\n title,\n model,\n messages,\n frozenAt,\n kind,\n live,\n ...(thawedAs ? { thawedAs } : {}),\n })\n );\n }\n\n thaw(id: string): Agent | null {\n const record = this.frozen().find((item) => item.id === id);\n if (!record) return null;\n if (record.live) {\n const running = this.list().find((agent) => agent.id === id) ?? null;\n if (running) this.select(id);\n return running;\n }\n const provisional = `thawing-${crypto.randomUUID()}`;\n const thawed = this.#connection.control.thaw(id, BACKGROUND_CONTEXT).then(\n (result) => result.id,\n () => null\n );\n this.#creating.set(provisional, thawed);\n void thawed.then((cone) => {\n if (this.#active !== provisional) return;\n this.#active = cone ?? CONE;\n this.emit('active', this.#active);\n this.emit('messages', this.#active);\n });\n return {\n id: provisional,\n name: record.name,\n kind: 'cone',\n parentId: null,\n status: 'idle',\n model: record.model,\n contextFill: 0,\n unread: 0,\n };\n }\n\n discard(id: string): void {\n attempt(\n this.#connection.control.discard(id, BACKGROUND_CONTEXT),\n 'discard frozen cones',\n this.#report(this.active())\n );\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type {\n Agent,\n AgentEvents,\n AgentPort,\n AgentStatus,\n FrozenCone,\n Message,\n Outgoing,\n SlashCommand,\n SystemMessage,\n Thinking,\n UserMessage,\n} from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { ConversationView } from '@earendil-works/pi-durable';\nimport type { AgentConnection } from '../client.ts';\nimport { contextRatio, contextTokens } from '../context.ts';\nimport { shrink } from '../images/fit.ts';\nimport { entryLick } from '../licks/state.ts';\nimport { type VaultHold, vaultHold } from '../secrets/view.ts';\nimport type { AgentSettingsChange, AgentSummary, Command } from '../services.ts';\nimport { shownLabel } from '../titles/shown.ts';\nimport { attempt } from './attempt.ts';\nimport { Emitter } from './emitter.ts';\nimport { CONNECT_IT, isBusy, providerName, queued, toMessages } from './messages.ts';\nimport { readUrl, sendAttachments } from './outgoing.ts';\nimport { merged, proposalNotices, proposalQueue } from './proposals.ts';\n\nexport const CONE = 'cone';\n\nconst thinking: Record<string, Thinking> = {\n off: 'off',\n minimal: 'low',\n low: 'low',\n medium: 'medium',\n high: 'high',\n xhigh: 'high',\n max: 'high',\n};\n\ninterface AgentDoc {\n model?: { provider: string; modelId: string };\n thinkingLevel?: string;\n}\n\nfunction status(view: ConversationView | undefined, messages: readonly Message[]): AgentStatus {\n if (isBusy(view)) {\n const live = view?.docs['pi.live'] as { tools?: { status: string }[] } | undefined;\n return live?.tools?.some((slot) => slot.status === 'running') ? 'working' : 'thinking';\n }\n const last = messages.at(-1);\n return last?.role === 'assistant' && last.status === 'error' ? 'error' : 'idle';\n}\n\nfunction answers(messages: readonly Message[]): string[] {\n return messages\n .filter((message) => message.role === 'assistant' && message.status !== 'streaming')\n .map((message) => message.id);\n}\n\nexport function slashCommand({ kind, ...command }: Command): SlashCommand {\n return kind === 'action' ? command : { ...command, kind };\n}\n\nexport type AgentHold = VaultHold;\n\nexport type AgentAdapterEvents = AgentEvents & { hold: AgentHold | null };\n\nfunction sameHold(a: AgentHold | null, b: AgentHold | null): boolean {\n return a === b || (a !== null && b !== null && a.reason === b.reason && a.held === b.held);\n}\n\ninterface Pending {\n agentId: string;\n message: UserMessage;\n dropped: boolean;\n release(): void;\n released: Promise<void>;\n}\n\nexport class AgentAdapter extends Emitter<AgentAdapterEvents> implements AgentPort {\n readonly #connection: AgentConnection;\n readonly #ready: Promise<void>;\n readonly #messages = new Map<string, Message[]>();\n #active: string | null = null;\n #creating = new Map<string, Promise<string | null>>();\n #hold: AgentHold | null = null;\n readonly #outbox = new Map<string, Pending>();\n readonly #notices = new Map<string, { at: number; message: SystemMessage }[]>();\n readonly #unread = new Map<string, number>();\n readonly #seen = new Map<string, Set<string>>();\n readonly #queuedAt = new Map<string, Map<string, { at: number; seen: boolean }>>();\n #opened: ReadonlySet<string> | null = null;\n readonly #agentCommandsCache = new Map<string, Command[]>();\n readonly #agentCommandsLoading = new Set<string>();\n #agentCommandsGeneration = 0;\n\n constructor(connection: AgentConnection) {\n super();\n this.#connection = connection;\n this.#hold = this.hold();\n connection.vault?.subscribe(() => {\n const next = this.hold();\n if (sameHold(next, this.#hold)) return;\n this.#hold = next;\n if (!next) for (const pending of this.#outbox.values()) pending.release();\n this.emit('hold', next);\n this.emit('agents', this.list());\n });\n connection.proposals?.subscribe(() => {\n const agentId = connection.guest?.agentId;\n if (agentId) this.emit('messages', agentId);\n });\n connection.frozen?.subscribe(() => {\n this.emit('frozen', this.frozen());\n this.emit('agents', this.list());\n });\n this.#ready = new Promise((resolve) => {\n connection.transcript.subscribe(() => {\n this.#refresh();\n resolve();\n });\n connection.deliveries.subscribe(() => this.#refresh());\n connection.views?.subscribe(() => this.#refresh());\n connection.agents?.subscribe(() => this.#refresh());\n });\n connection.settings?.state.subscribe(() => {\n this.emit('agents', this.list());\n this.#refresh();\n });\n const stale = () => {\n this.#agentCommandsGeneration += 1;\n this.#agentCommandsLoading.clear();\n this.#agentCommandsCache.clear();\n this.emit('agents', this.list());\n };\n connection.commands?.subscribe(stale);\n connection.privateRevision?.subscribe(stale);\n }\n\n #summary(): readonly AgentSummary[] {\n const agents = this.#connection.agents?.value?.agents;\n return agents?.length\n ? agents\n : [{ id: CONE, name: 'sliccy', kind: 'cone', parentId: null, role: null }];\n }\n\n #view(agentId: string = this.active()): ConversationView | undefined {\n const views = this.#connection.views?.value;\n const view = views?.[agentId];\n if (view) return view;\n const cone = this.#connection.agents?.value?.active ?? CONE;\n return agentId === cone ? this.#connection.transcript.value : undefined;\n }\n\n #refresh(): void {\n this.#active ??= this.#connection.agents?.value?.active ?? null;\n if (!this.#opened && (!this.#connection.agents || this.#connection.agents.value))\n this.#opened = new Set(this.#summary().map((summary) => summary.id));\n for (const summary of this.#summary()) this.#stamp(summary.id, this.#view(summary.id));\n this.emit('agents', this.list());\n let unread = false;\n for (const summary of this.#summary()) unread = this.#update(summary.id) || unread;\n for (const id of [...this.#messages.keys(), ...this.#notices.keys(), ...this.#seen.keys()])\n if (!this.#summary().some((summary) => summary.id === id)) {\n this.#messages.delete(id);\n this.#notices.delete(id);\n this.#seen.delete(id);\n this.#unread.delete(id);\n this.#queuedAt.delete(id);\n }\n if (unread) this.emit('agents', this.list());\n }\n\n #count(agentId: string, view: ConversationView, messages: readonly Message[]): boolean {\n const ids = answers(messages);\n const known = this.#seen.get(agentId);\n if (agentId === this.active() || (!known && (!this.#opened || this.#opened.has(agentId)))) {\n this.#seen.set(agentId, new Set(ids));\n return false;\n }\n const seen = known ?? new Set<string>();\n this.#seen.set(agentId, seen);\n const fresh = isBusy(view) ? [] : ids.filter((id) => !seen.has(id));\n if (!fresh.length) return false;\n for (const id of fresh) seen.add(id);\n this.#unread.set(agentId, (this.#unread.get(agentId) ?? 0) + fresh.length);\n return true;\n }\n\n notify(text: string, agentId: string = this.active()): void {\n this.#note(agentId, { kind: 'notice', text });\n }\n\n #note(agentId: string, shown: Pick<SystemMessage, 'kind' | 'text' | 'title' | 'action'>): void {\n const notes = this.#notices.get(agentId) ?? [];\n notes.push({\n at: this.#messages.get(agentId)?.length ?? 0,\n message: { id: `n${crypto.randomUUID()}`, role: 'system', ...shown, createdAt: Date.now() },\n });\n this.#notices.set(agentId, notes);\n this.emit('messages', agentId);\n }\n\n #unconnected(agentId: string, submissionId: string): void {\n const provider = this.list()\n .find((row) => row.id === agentId)\n ?.model.split('/')[0];\n const accounts = this.#connection.settings?.state.value?.accounts ?? [];\n const account = accounts.find((item) => item.id === provider);\n if (!account || account.status === 'connected') return;\n const title = `${providerName(account.id, account.provider)} isn't connected.`;\n this.#connection.control.wait(submissionId, BACKGROUND_CONTEXT).then(\n (settled) => {\n if (settled.status === 'unanswered' && settled.reason === 'no_model')\n this.#note(agentId, {\n kind: 'error',\n title,\n text: CONNECT_IT,\n action: 'settings',\n });\n },\n () => undefined\n );\n }\n\n #report(agentId: string): (text: string) => void {\n return (text) => this.notify(text, agentId);\n }\n\n #update(agentId: string): boolean {\n const view = this.#view(agentId);\n if (!view) return false;\n const before = this.#messages.get(agentId) ?? [];\n const after = this.#labelled(toMessages(view, this.#connection.deliveries.value));\n this.#messages.set(agentId, after);\n if (before.length !== after.length) this.emit('messages', agentId);\n else {\n const changed = after.filter(\n (message, index) => JSON.stringify(message) !== JSON.stringify(before[index])\n );\n if (changed.length === 1) this.emit('message', { agentId, message: changed[0] as Message });\n else if (changed.length > 1) this.emit('messages', agentId);\n }\n return this.#count(agentId, view, after);\n }\n\n #labelled(messages: Message[]): Message[] {\n const state = this.#connection.settings?.state.value;\n const labels = state?.labels ?? {};\n const known = new Set((state?.models ?? []).map((model) => model.id));\n return messages.map((message) =>\n message.role === 'assistant' &&\n message.model &&\n !known.has(message.model) &&\n labels[message.model]\n ? { ...message, model: labels[message.model] as string }\n : message\n );\n }\n\n ready(): Promise<void> {\n return this.#ready;\n }\n\n hold(): AgentHold | null {\n return vaultHold(this.#connection.vault?.value);\n }\n\n list(): readonly Agent[] {\n const rows = this.#connection.frozen?.value ?? [];\n return this.#summary().map((summary) => {\n const view = this.#view(summary.id);\n const doc = view?.docs['pi.agent'] as AgentDoc | undefined;\n const title = rows.find((row) => row.id === summary.id)?.title;\n const model = doc?.model ? `${doc.model.provider}/${doc.model.modelId}` : '';\n const models = this.#connection.settings?.state.value?.models ?? [];\n return {\n id: summary.id,\n name: summary.role ? `${summary.name} \u00B7 ${summary.role}` : summary.name,\n kind: summary.kind,\n parentId: summary.parentId,\n status: this.#status(summary.id, status(view, this.#messages.get(summary.id) ?? [])),\n model,\n contextFill: contextRatio(contextTokens(view), model, models) ?? 0,\n unread: this.#unread.get(summary.id) ?? 0,\n thinking: thinking[doc?.thinkingLevel ?? 'off'] ?? 'off',\n ...(title ? { title } : {}),\n };\n });\n }\n\n active(): string {\n const known = this.#summary();\n if (this.#active && this.#creating.has(this.#active)) return this.#active;\n if (this.#active && known.some((summary) => summary.id === this.#active)) return this.#active;\n return this.#connection.agents?.value?.active ?? CONE;\n }\n\n select(id: string): void {\n if (this.#creating.has(id)) {\n this.#active = id;\n this.emit('active', id);\n return;\n }\n const found = this.#summary().find((summary) => summary.id === id);\n if (!found) return;\n this.#active = id;\n this.#seen.set(id, new Set(answers(this.#messages.get(id) ?? [])));\n const read = this.#unread.delete(id);\n if (found.kind === 'cone')\n attempt(\n this.#connection.control.selectCone(id, BACKGROUND_CONTEXT),\n 'switch cones',\n this.#report(id)\n );\n this.emit('active', id);\n this.emit('messages', id);\n if (read) this.emit('agents', this.list());\n }\n\n messages(agentId: string = this.active()): readonly Message[] {\n const listed = this.#listed(agentId);\n const guest = this.#connection.guest;\n if (!guest || guest.agentId !== agentId) return listed;\n return merged(listed, proposalNotices(this.#connection.proposals?.value));\n }\n\n #listed(agentId: string): readonly Message[] {\n const shown = this.#messages.get(agentId) ?? [];\n const notes = this.#notices.get(agentId);\n if (!notes) return shown;\n const at = (index: number) => notes.filter((note) => note.at === index).map((n) => n.message);\n const late = notes.filter((note) => note.at >= shown.length).map((note) => note.message);\n return [...shown.flatMap((message, index) => [...at(index), message]), ...late];\n }\n\n async send(agentId: string, input: string | Outgoing): Promise<void> {\n const outgoing = typeof input === 'string' ? { text: input } : input;\n const attachments = outgoing.attachments?.length\n ? await sendAttachments(outgoing.attachments, readUrl, shrink, (ref) =>\n this.#connection.control.image(ref, BACKGROUND_CONTEXT)\n ).catch((error: Error) => {\n this.notify(error.message, agentId);\n return null;\n })\n : [];\n if (!attachments) return;\n const target = this.#creating.has(agentId) ? await this.#creating.get(agentId) : agentId;\n if (target === null) throw new Error('The scoop could not be created.');\n const pending = target && this.#held(target) ? this.#pending(target, outgoing) : undefined;\n if (pending) await pending.released;\n if (pending?.dropped) return this.#settle(pending);\n const at = Date.now();\n const sent = await this.#connection.control\n .send(\n {\n text: outgoing.text,\n whenBusy: outgoing.mode === 'queue' ? 'followUp' : 'steer',\n requestId: crypto.randomUUID(),\n agentId: target || null,\n ...(attachments.length ? { attachments } : {}),\n },\n BACKGROUND_CONTEXT\n )\n .finally(() => pending && this.#settle(pending));\n if (!sent.accepted) throw new Error(sent.error.message);\n this.#sent(target || agentId, `q${sent.submissionId}`, at);\n this.#unconnected(target || agentId, sent.submissionId);\n if (pending?.dropped)\n attempt(\n this.#connection.control.unqueue(pending.agentId, sent.submissionId, BACKGROUND_CONTEXT),\n 'remove queued messages',\n this.#report(pending.agentId)\n );\n }\n\n #stamps(agentId: string): Map<string, { at: number; seen: boolean }> {\n const stamps = this.#queuedAt.get(agentId) ?? new Map();\n this.#queuedAt.set(agentId, stamps);\n return stamps;\n }\n\n #sent(agentId: string, id: string, at: number): void {\n const stamps = this.#stamps(agentId);\n const known = stamps.get(id);\n stamps.set(id, { at: Math.min(at, known?.at ?? at), seen: known?.seen ?? false });\n }\n\n #stamp(agentId: string, view: ConversationView | undefined): void {\n const stamps = this.#stamps(agentId);\n const ids = new Set(queued(view).map((message) => message.id));\n const now = Date.now();\n for (const id of ids) stamps.set(id, { at: stamps.get(id)?.at ?? now, seen: true });\n for (const [id, stamp] of stamps)\n if (!ids.has(id) && (stamp.seen || (!ids.size && !isBusy(view)))) stamps.delete(id);\n }\n\n #pending(agentId: string, outgoing: Outgoing): Pending {\n const id = `p${crypto.randomUUID()}`;\n const message: UserMessage = {\n id,\n role: 'user',\n text: outgoing.text,\n createdAt: Date.now(),\n ...(outgoing.attachments?.length ? { attachments: [...outgoing.attachments] } : {}),\n queued: true,\n mode: outgoing.mode === 'queue' ? 'queue' : 'steer',\n };\n const { promise: released, resolve: release } = Promise.withResolvers<void>();\n const pending = { agentId, message, dropped: false, release, released };\n this.#outbox.set(id, pending);\n this.emit('messages', agentId);\n return pending;\n }\n\n #settle(pending: Pending): void {\n this.#outbox.delete(pending.message.id);\n this.emit('messages', pending.agentId);\n }\n\n async rewind(agentId: string, messageId: string): Promise<Outgoing | null> {\n const rewound = await this.#connection.control.rewindAgent(\n agentId,\n messageId,\n BACKGROUND_CONTEXT\n );\n if (!rewound.done) return null;\n return rewound.attachments?.length\n ? { text: rewound.text, attachments: rewound.attachments }\n : { text: rewound.text };\n }\n\n stop(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.stopAgent(agentId, BACKGROUND_CONTEXT),\n 'stop agents',\n this.#report(agentId)\n );\n }\n\n busy(agentId: string = this.active()): boolean {\n return isBusy(this.#view(agentId)) || this.#held(agentId);\n }\n\n #status(agentId: string, shown: AgentStatus): AgentStatus {\n return shown === 'idle' && this.#held(agentId) ? 'working' : shown;\n }\n\n #held(agentId: string): boolean {\n return this.#hold !== null && agentId === (this.#connection.agents?.value?.active ?? CONE);\n }\n\n queue(agentId: string = this.active()): readonly UserMessage[] {\n const pending = [...this.#outbox.values()]\n .filter((item) => item.agentId === agentId && !item.dropped)\n .map((item) => item.message);\n const stamps = this.#queuedAt.get(agentId);\n const at = (id: string) => stamps?.get(id)?.at ?? 0;\n const guest = this.#connection.guest;\n const proposed =\n guest && guest.agentId === agentId\n ? proposalQueue(this.#connection.proposals?.value, guest.label)\n : [];\n return [...queued(this.#view(agentId), at), ...proposed, ...pending];\n }\n\n unqueue(agentId: string, messageId: string): void {\n const pending = this.#outbox.get(messageId);\n if (pending) {\n pending.dropped = true;\n pending.release();\n this.emit('messages', pending.agentId);\n return;\n }\n attempt(\n this.#connection.control.unqueue(agentId, messageId.replace(/^q/, ''), BACKGROUND_CONTEXT),\n 'remove queued messages',\n this.#report(agentId)\n );\n }\n\n suggestion(): string | null {\n return null;\n }\n\n answer(): void {}\n\n resolveLick(agentId: string, messageId: string, state: 'confirmed' | 'dismissed'): void {\n const message = this.messages(agentId).find((candidate) => candidate.id === messageId);\n const entry = this.#view(agentId)?.entries.find(\n (candidate) => `e${candidate.id}` === messageId\n );\n const lick = message?.role === 'lick' && entry ? entryLick(entry) : undefined;\n if (lick)\n attempt(\n this.#connection.control.resolveAgentLick(agentId, lick.id, state, BACKGROUND_CONTEXT),\n 'answer licks',\n this.#report(agentId)\n );\n }\n\n compact(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.compactAgent(agentId, null, BACKGROUND_CONTEXT),\n 'compact conversations',\n this.#report(agentId)\n );\n }\n\n clear(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.newChat(agentId, BACKGROUND_CONTEXT),\n 'start new chats',\n this.#report(agentId)\n );\n }\n\n freeze(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.freeze(agentId, BACKGROUND_CONTEXT),\n 'freeze cones',\n this.#report(agentId)\n );\n }\n\n #configure(agentId: string, change: Partial<AgentSettingsChange>): void {\n attempt(\n this.#connection.control.configure(\n {\n model: change.model ?? null,\n thinkingLevel: change.thinkingLevel ?? null,\n agentId,\n },\n BACKGROUND_CONTEXT\n ),\n 'change agent settings',\n this.#report(agentId)\n );\n }\n\n setModel(agentId: string, model: string): void {\n const at = model.indexOf('/');\n if (at <= 0) return;\n this.#configure(agentId, {\n model: { provider: model.slice(0, at), modelId: model.slice(at + 1) },\n });\n }\n\n setThinking(agentId: string, level: Thinking): void {\n this.#configure(agentId, { thinkingLevel: level });\n }\n\n async older(): Promise<readonly Message[]> {\n return [];\n }\n\n #fetchCommands(agentId: string): void {\n if (this.#agentCommandsLoading.has(agentId)) return;\n if (typeof this.#connection.control.agentCommands !== 'function') return;\n this.#agentCommandsLoading.add(agentId);\n const generation = this.#agentCommandsGeneration;\n this.#connection.control\n .agentCommands(agentId, BACKGROUND_CONTEXT)\n .then((commands) => {\n if (generation !== this.#agentCommandsGeneration) return;\n this.#agentCommandsCache.set(agentId, commands);\n this.emit('agents', this.list());\n })\n .catch(() => undefined)\n .finally(() => {\n if (generation === this.#agentCommandsGeneration)\n this.#agentCommandsLoading.delete(agentId);\n });\n }\n\n commands(agentId: string = this.active()): readonly SlashCommand[] {\n const cached = this.#agentCommandsCache.get(agentId);\n if (cached) return cached.map(slashCommand);\n this.#fetchCommands(agentId);\n return (this.#connection.commands?.value ?? []).map(slashCommand);\n }\n\n createScoop(parentId: string, name: string): Agent {\n const provisional = `scoop:creating-${crypto.randomUUID()}`;\n const created = this.#connection.control.createScoop(parentId, name, BACKGROUND_CONTEXT).then(\n (result) => result.id,\n () => null\n );\n this.#creating.set(provisional, created);\n void created.then((id) => {\n if (this.#active !== provisional) return;\n this.#active = id ?? parentId;\n this.emit('active', this.#active);\n this.emit('messages', this.#active);\n });\n return {\n id: provisional,\n name,\n kind: 'scoop',\n parentId,\n status: 'idle',\n model: '',\n contextFill: 0,\n unread: 0,\n };\n }\n\n async drop(agentId: string): Promise<void> {\n const parent = this.#summary().find((summary) => summary.id === agentId)?.parentId ?? CONE;\n const dropped = await this.#connection.control.drop(agentId, BACKGROUND_CONTEXT);\n if (dropped.error !== null) throw new Error(dropped.error);\n if (this.#active === agentId) this.select(parent);\n }\n\n async createCone(name: string): Promise<Agent> {\n const created = await this.#connection.control.createCone(name, BACKGROUND_CONTEXT);\n if (created.error !== null) throw new Error(created.error);\n return {\n id: created.id,\n name: name.trim(),\n kind: 'cone',\n parentId: null,\n status: 'idle',\n model: '',\n contextFill: 0,\n unread: 0,\n };\n }\n\n async toolLabel(agentId: string, callIds: readonly string[]): Promise<string | null> {\n const shown = shownLabel(this.#connection.labels?.value, callIds);\n if (shown !== undefined) return shown;\n return this.#connection.control\n .toolLabel(agentId, [...callIds], BACKGROUND_CONTEXT)\n .catch(() => null);\n }\n\n frozen(): readonly FrozenCone[] {\n return (this.#connection.frozen?.value ?? []).map(\n ({ id, name, title, model, messages, frozenAt, kind, live, thawedAs }) => ({\n id,\n name,\n title,\n model,\n messages,\n frozenAt,\n kind,\n live,\n ...(thawedAs ? { thawedAs } : {}),\n })\n );\n }\n\n thaw(id: string): Agent | null {\n const record = this.frozen().find((item) => item.id === id);\n if (!record) return null;\n if (record.live) {\n const running = this.list().find((agent) => agent.id === id) ?? null;\n if (running) this.select(id);\n return running;\n }\n const provisional = `thawing-${crypto.randomUUID()}`;\n const thawed = this.#connection.control.thaw(id, BACKGROUND_CONTEXT).then(\n (result) => result.id,\n () => null\n );\n this.#creating.set(provisional, thawed);\n void thawed.then((cone) => {\n if (this.#active !== provisional) return;\n this.#active = cone ?? CONE;\n this.emit('active', this.#active);\n this.emit('messages', this.#active);\n });\n return {\n id: provisional,\n name: record.name,\n kind: 'cone',\n parentId: null,\n status: 'idle',\n model: record.model,\n contextFill: 0,\n unread: 0,\n };\n }\n\n discard(id: string): void {\n attempt(\n this.#connection.control.discard(id, BACKGROUND_CONTEXT),\n 'discard frozen cones',\n this.#report(this.active())\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -64,7 +64,7 @@ class ApprovalsAdapter extends Emitter {
|
|
|
64
64
|
super();
|
|
65
65
|
this.#connection = connection;
|
|
66
66
|
this.#host = host;
|
|
67
|
-
this.#ours = !connection.readOnly
|
|
67
|
+
this.#ours = !connection.readOnly;
|
|
68
68
|
if (this.#ours || host?.decide) this.decide = (...args) => this.#route(...args);
|
|
69
69
|
this.#listed = new Set(this.#agent().map((approval) => approval.id));
|
|
70
70
|
connection.approvals?.subscribe(() => this.#changed());
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/spectrum/approvals-port.ts"],
|
|
4
|
-
"sourcesContent": ["import type {\n Approval,\n ApprovalDecision,\n ApprovalEnd,\n ApprovalRequester,\n ApprovalsEvents,\n ApprovalsPort,\n} from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { Approval as Item } from '../approvals/record.ts';\nimport type { AgentConnection } from '../client.ts';\nimport { Emitter } from './emitter.ts';\n\nconst ENDS: Record<string, ApprovalEnd> = {\n approved: 'answered',\n rejected: 'answered',\n unanswered: 'expired',\n withdrawn: 'withdrawn',\n};\n\nfunction requesterOf(item: Item): ApprovalRequester {\n const { kind, name, agentId, where } = item.requester;\n return {\n kind,\n name,\n ...(agentId ? { agentId } : {}),\n ...(where ? { where } : {}),\n };\n}\n\nexport function shown(item: Item, agentName: string | undefined): Approval {\n const base = {\n id: item.id,\n requester: requesterOf(item),\n createdAt: item.createdAt,\n expiresAt: item.expiresAt,\n };\n if (item.kind === 'sudo') {\n const { command, target, cwd, alwaysScope } = item.detail;\n return {\n ...base,\n kind: 'sudo',\n command,\n ...(target ? { target } : {}),\n ...(cwd ? { cwd } : {}),\n always: item.always,\n ...(alwaysScope ? { alwaysScope } : {}),\n };\n }\n const guest = {\n ...base,\n agentId: item.agentId,\n ...(agentName ? { agentName } : {}),\n always: false as const,\n ...(item.verdict && item.verdict.decision !== 'unsure'\n ? { verdict: { decision: item.verdict.decision, reason: item.verdict.reason } }\n : {}),\n };\n if (item.kind === 'guest-tool')\n return { ...guest, kind: 'guest-tool', tool: item.detail.tool, summary: item.detail.summary };\n return {\n ...guest,\n kind: 'guest-message',\n text: item.detail.text,\n ...(item.detail.attachments.length\n ? { attachments: item.detail.attachments.map((file) => ({ ...file })) }\n : {}),\n };\n}\n\nexport type HostApprovals = ApprovalsPort;\n\nexport const NOT_HERE = \"This request can't be answered in this tab.\";\n\nconst asked = (item: Item) => item.state === 'pending' && item.tier === 'user';\n\nexport class ApprovalsAdapter extends Emitter<ApprovalsEvents> implements ApprovalsPort {\n readonly #connection: AgentConnection;\n readonly #host: HostApprovals | undefined;\n readonly #ours: boolean;\n readonly #mine = new Set<string>();\n readonly #deciding = new Set<string>();\n #listed = new Set<string>();\n readonly decide?: (id: string, decision: ApprovalDecision, reason?: string) => Promise<void>;\n\n constructor(connection: AgentConnection, host?: HostApprovals) {\n super();\n this.#connection = connection;\n this.#host = host;\n this.#ours = !connection.readOnly
|
|
5
|
-
"mappings": "AAQA,SAAS,0BAA0B;AAGnC,SAAS,eAAe;AAExB,MAAM,OAAoC;AAAA,EACxC,UAAU;AAAA,EACV,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,WAAW;AACb;AAEA,SAAS,YAAY,MAA+B;AAClD,QAAM,EAAE,MAAM,MAAM,SAAS,MAAM,IAAI,KAAK;AAC5C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC7B,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,EAC3B;AACF;AAEO,SAAS,MAAM,MAAY,WAAyC;AACzE,QAAM,OAAO;AAAA,IACX,IAAI,KAAK;AAAA,IACT,WAAW,YAAY,IAAI;AAAA,IAC3B,WAAW,KAAK;AAAA,IAChB,WAAW,KAAK;AAAA,EAClB;AACA,MAAI,KAAK,SAAS,QAAQ;AACxB,UAAM,EAAE,SAAS,QAAQ,KAAK,YAAY,IAAI,KAAK;AACnD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,MACN;AAAA,MACA,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,MAC3B,GAAI,MAAM,EAAE,IAAI,IAAI,CAAC;AAAA,MACrB,QAAQ,KAAK;AAAA,MACb,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,IACvC;AAAA,EACF;AACA,QAAM,QAAQ;AAAA,IACZ,GAAG;AAAA,IACH,SAAS,KAAK;AAAA,IACd,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjC,QAAQ;AAAA,IACR,GAAI,KAAK,WAAW,KAAK,QAAQ,aAAa,WAC1C,EAAE,SAAS,EAAE,UAAU,KAAK,QAAQ,UAAU,QAAQ,KAAK,QAAQ,OAAO,EAAE,IAC5E,CAAC;AAAA,EACP;AACA,MAAI,KAAK,SAAS;AAChB,WAAO,EAAE,GAAG,OAAO,MAAM,cAAc,MAAM,KAAK,OAAO,MAAM,SAAS,KAAK,OAAO,QAAQ;AAC9F,SAAO;AAAA,IACL,GAAG;AAAA,IACH,MAAM;AAAA,IACN,MAAM,KAAK,OAAO;AAAA,IAClB,GAAI,KAAK,OAAO,YAAY,SACxB,EAAE,aAAa,KAAK,OAAO,YAAY,IAAI,CAAC,UAAU,EAAE,GAAG,KAAK,EAAE,EAAE,IACpE,CAAC;AAAA,EACP;AACF;AAIO,MAAM,WAAW;AAExB,MAAM,QAAQ,CAAC,SAAe,KAAK,UAAU,aAAa,KAAK,SAAS;AAEjE,MAAM,yBAAyB,QAAkD;AAAA,EAC7E;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ,oBAAI,IAAY;AAAA,EACxB,YAAY,oBAAI,IAAY;AAAA,EACrC,UAAU,oBAAI,IAAY;AAAA,EACjB;AAAA,EAET,YAAY,YAA6B,MAAsB;AAC7D,UAAM;AACN,SAAK,cAAc;AACnB,SAAK,QAAQ;AACb,SAAK,QAAQ,CAAC,WAAW
|
|
4
|
+
"sourcesContent": ["import type {\n Approval,\n ApprovalDecision,\n ApprovalEnd,\n ApprovalRequester,\n ApprovalsEvents,\n ApprovalsPort,\n} from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { Approval as Item } from '../approvals/record.ts';\nimport type { AgentConnection } from '../client.ts';\nimport { Emitter } from './emitter.ts';\n\nconst ENDS: Record<string, ApprovalEnd> = {\n approved: 'answered',\n rejected: 'answered',\n unanswered: 'expired',\n withdrawn: 'withdrawn',\n};\n\nfunction requesterOf(item: Item): ApprovalRequester {\n const { kind, name, agentId, where } = item.requester;\n return {\n kind,\n name,\n ...(agentId ? { agentId } : {}),\n ...(where ? { where } : {}),\n };\n}\n\nexport function shown(item: Item, agentName: string | undefined): Approval {\n const base = {\n id: item.id,\n requester: requesterOf(item),\n createdAt: item.createdAt,\n expiresAt: item.expiresAt,\n };\n if (item.kind === 'sudo') {\n const { command, target, cwd, alwaysScope } = item.detail;\n return {\n ...base,\n kind: 'sudo',\n command,\n ...(target ? { target } : {}),\n ...(cwd ? { cwd } : {}),\n always: item.always,\n ...(alwaysScope ? { alwaysScope } : {}),\n };\n }\n const guest = {\n ...base,\n agentId: item.agentId,\n ...(agentName ? { agentName } : {}),\n always: false as const,\n ...(item.verdict && item.verdict.decision !== 'unsure'\n ? { verdict: { decision: item.verdict.decision, reason: item.verdict.reason } }\n : {}),\n };\n if (item.kind === 'guest-tool')\n return { ...guest, kind: 'guest-tool', tool: item.detail.tool, summary: item.detail.summary };\n return {\n ...guest,\n kind: 'guest-message',\n text: item.detail.text,\n ...(item.detail.attachments.length\n ? { attachments: item.detail.attachments.map((file) => ({ ...file })) }\n : {}),\n };\n}\n\nexport type HostApprovals = ApprovalsPort;\n\nexport const NOT_HERE = \"This request can't be answered in this tab.\";\n\nconst asked = (item: Item) => item.state === 'pending' && item.tier === 'user';\n\nexport class ApprovalsAdapter extends Emitter<ApprovalsEvents> implements ApprovalsPort {\n readonly #connection: AgentConnection;\n readonly #host: HostApprovals | undefined;\n readonly #ours: boolean;\n readonly #mine = new Set<string>();\n readonly #deciding = new Set<string>();\n #listed = new Set<string>();\n readonly decide?: (id: string, decision: ApprovalDecision, reason?: string) => Promise<void>;\n\n constructor(connection: AgentConnection, host?: HostApprovals) {\n super();\n this.#connection = connection;\n this.#host = host;\n this.#ours = !connection.readOnly;\n if (this.#ours || host?.decide) this.decide = (...args) => this.#route(...args);\n this.#listed = new Set(this.#agent().map((approval) => approval.id));\n connection.approvals?.subscribe(() => this.#changed());\n host?.on('approvals', () => this.emit('approvals', this.list()));\n host?.on('ended', (detail) => this.emit('ended', detail));\n }\n\n #items(): readonly Item[] {\n return this.#connection.approvals?.value ?? [];\n }\n\n list(): readonly Approval[] {\n return [...(this.#host?.list() ?? []), ...this.#agent()].sort(\n (a, b) => a.createdAt - b.createdAt\n );\n }\n\n #agent(): readonly Approval[] {\n const names = new Map(\n (this.#connection.agents?.value?.agents ?? []).map((agent) => [agent.id, agent.name])\n );\n return this.#items()\n .filter((item) => asked(item) && !this.#mine.has(item.id))\n .sort((a, b) => a.createdAt - b.createdAt)\n .map((item) => shown(item, names.get(item.agentId)));\n }\n\n #changed(): void {\n const items = new Map(this.#items().map((item) => [item.id, item]));\n const listed = this.#agent();\n const now = new Set(listed.map((approval) => approval.id));\n for (const id of this.#listed) {\n if (now.has(id) || this.#mine.has(id) || this.#deciding.has(id)) continue;\n const state = items.get(id)?.state;\n this.emit('ended', { id, reason: (state && ENDS[state]) || 'answered' });\n }\n for (const id of this.#mine) {\n const item = items.get(id);\n if (!item || !asked(item)) this.#mine.delete(id);\n }\n this.#listed = now;\n this.emit('approvals', this.list());\n }\n\n #route(id: string, decision: ApprovalDecision, reason?: string): Promise<void> {\n const host = this.#host;\n if (host?.list().some((approval) => approval.id === id)) {\n if (!host.decide) return Promise.reject(new Error(NOT_HERE));\n return host.decide(id, decision, reason);\n }\n if (!this.#ours) return Promise.reject(new Error(NOT_HERE));\n return this.#decide(id, decision, reason);\n }\n\n async #decide(id: string, decision: ApprovalDecision, reason?: string): Promise<void> {\n this.#deciding.add(id);\n try {\n const answer = await this.#connection.control.decide(\n id,\n decision,\n reason ?? null,\n BACKGROUND_CONTEXT\n );\n if (!answer.done) throw new Error(answer.error);\n this.#mine.add(id);\n } finally {\n this.#deciding.delete(id);\n }\n this.#changed();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -17,8 +17,7 @@ class GuestAdapter extends Emitter {
|
|
|
17
17
|
}
|
|
18
18
|
unavailable() {
|
|
19
19
|
const connection = this.#connection;
|
|
20
|
-
if (connection.
|
|
21
|
-
return NO_CONTROL;
|
|
20
|
+
if (connection.viewOnly || connection.guest || !connection.guests) return NO_CONTROL;
|
|
22
21
|
if (connection.owner === false) return NO_OWNER;
|
|
23
22
|
return this.#hub ? null : NO_HUB;
|
|
24
23
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/spectrum/guest-port.ts"],
|
|
4
|
-
"sourcesContent": ["import type { GuestDraft, GuestEvents, GuestPort, GuestSeat } from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { AgentConnection } from '../client.ts';\nimport { Emitter } from './emitter.ts';\n\nexport interface GuestHub {\n mint(request: GuestDraft & { agentId: string }): Promise<{ id: string; url: string }>;\n revoke(id: string): Promise<void>;\n}\n\nexport const NO_HUB = 'Inviting guests needs the tray hub.';\nexport const NO_CONTROL = 'Only a tab with Control can invite guests.';\nexport const NO_OWNER = \"Only the owner's tab can invite guests.\";\n\nexport class GuestAdapter extends Emitter<GuestEvents> implements GuestPort {\n readonly #connection: AgentConnection;\n readonly #hub: GuestHub | null;\n\n constructor(connection: AgentConnection, hub: GuestHub | null) {\n super();\n this.#connection = connection;\n this.#hub = hub;\n connection.guests?.subscribe(() => this.emit('seats', this.list()));\n }\n\n list(): readonly GuestSeat[] {\n return this.#connection.guests?.value ?? [];\n }\n\n unavailable(): string | null {\n const connection = this.#connection;\n if (connection.
|
|
5
|
-
"mappings": "AACA,SAAS,0BAA0B;AAEnC,SAAS,eAAe;AAOjB,MAAM,SAAS;AACf,MAAM,aAAa;AACnB,MAAM,WAAW;AAEjB,MAAM,qBAAqB,QAA0C;AAAA,EACjE;AAAA,EACA;AAAA,EAET,YAAY,YAA6B,KAAsB;AAC7D,UAAM;AACN,SAAK,cAAc;AACnB,SAAK,OAAO;AACZ,eAAW,QAAQ,UAAU,MAAM,KAAK,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC;AAAA,EACpE;AAAA,EAEA,OAA6B;AAC3B,WAAO,KAAK,YAAY,QAAQ,SAAS,CAAC;AAAA,EAC5C;AAAA,EAEA,cAA6B;AAC3B,UAAM,aAAa,KAAK;AACxB,QAAI,WAAW,YAAY,WAAW,
|
|
4
|
+
"sourcesContent": ["import type { GuestDraft, GuestEvents, GuestPort, GuestSeat } from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { AgentConnection } from '../client.ts';\nimport { Emitter } from './emitter.ts';\n\nexport interface GuestHub {\n mint(request: GuestDraft & { agentId: string }): Promise<{ id: string; url: string }>;\n revoke(id: string): Promise<void>;\n}\n\nexport const NO_HUB = 'Inviting guests needs the tray hub.';\nexport const NO_CONTROL = 'Only a tab with Control can invite guests.';\nexport const NO_OWNER = \"Only the owner's tab can invite guests.\";\n\nexport class GuestAdapter extends Emitter<GuestEvents> implements GuestPort {\n readonly #connection: AgentConnection;\n readonly #hub: GuestHub | null;\n\n constructor(connection: AgentConnection, hub: GuestHub | null) {\n super();\n this.#connection = connection;\n this.#hub = hub;\n connection.guests?.subscribe(() => this.emit('seats', this.list()));\n }\n\n list(): readonly GuestSeat[] {\n return this.#connection.guests?.value ?? [];\n }\n\n unavailable(): string | null {\n const connection = this.#connection;\n if (connection.viewOnly || connection.guest || !connection.guests) return NO_CONTROL;\n if (connection.owner === false) return NO_OWNER;\n return this.#hub ? null : NO_HUB;\n }\n\n async mint(agentId: string, draft: GuestDraft): Promise<{ seat: GuestSeat; url: string }> {\n const problem = this.unavailable();\n if (problem) throw new Error(problem);\n const hub = this.#hub as GuestHub;\n const gates = { messages: draft.gates.messages, tools: draft.gates.tools };\n const minted = await hub.mint({\n label: draft.label,\n expiresAt: draft.expiresAt,\n gates,\n agentId,\n });\n const opened = await this.#connection.control\n .guestOpen(\n { id: minted.id, label: draft.label, agentId, expiresAt: draft.expiresAt, gates },\n BACKGROUND_CONTEXT\n )\n .catch((error: Error) => ({ seat: null, error: error.message }));\n if (!opened.seat) {\n await hub.revoke(minted.id).catch(() => undefined);\n throw new Error(opened.error);\n }\n return { seat: opened.seat, url: minted.url };\n }\n\n async revoke(id: string): Promise<void> {\n await this.#connection.control.guestRevoke(id, BACKGROUND_CONTEXT);\n await this.#hub?.revoke(id);\n }\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,0BAA0B;AAEnC,SAAS,eAAe;AAOjB,MAAM,SAAS;AACf,MAAM,aAAa;AACnB,MAAM,WAAW;AAEjB,MAAM,qBAAqB,QAA0C;AAAA,EACjE;AAAA,EACA;AAAA,EAET,YAAY,YAA6B,KAAsB;AAC7D,UAAM;AACN,SAAK,cAAc;AACnB,SAAK,OAAO;AACZ,eAAW,QAAQ,UAAU,MAAM,KAAK,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC;AAAA,EACpE;AAAA,EAEA,OAA6B;AAC3B,WAAO,KAAK,YAAY,QAAQ,SAAS,CAAC;AAAA,EAC5C;AAAA,EAEA,cAA6B;AAC3B,UAAM,aAAa,KAAK;AACxB,QAAI,WAAW,YAAY,WAAW,SAAS,CAAC,WAAW,OAAQ,QAAO;AAC1E,QAAI,WAAW,UAAU,MAAO,QAAO;AACvC,WAAO,KAAK,OAAO,OAAO;AAAA,EAC5B;AAAA,EAEA,MAAM,KAAK,SAAiB,OAA8D;AACxF,UAAM,UAAU,KAAK,YAAY;AACjC,QAAI,QAAS,OAAM,IAAI,MAAM,OAAO;AACpC,UAAM,MAAM,KAAK;AACjB,UAAM,QAAQ,EAAE,UAAU,MAAM,MAAM,UAAU,OAAO,MAAM,MAAM,MAAM;AACzE,UAAM,SAAS,MAAM,IAAI,KAAK;AAAA,MAC5B,OAAO,MAAM;AAAA,MACb,WAAW,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,IACF,CAAC;AACD,UAAM,SAAS,MAAM,KAAK,YAAY,QACnC;AAAA,MACC,EAAE,IAAI,OAAO,IAAI,OAAO,MAAM,OAAO,SAAS,WAAW,MAAM,WAAW,MAAM;AAAA,MAChF;AAAA,IACF,EACC,MAAM,CAAC,WAAkB,EAAE,MAAM,MAAM,OAAO,MAAM,QAAQ,EAAE;AACjE,QAAI,CAAC,OAAO,MAAM;AAChB,YAAM,IAAI,OAAO,OAAO,EAAE,EAAE,MAAM,MAAM,MAAS;AACjD,YAAM,IAAI,MAAM,OAAO,KAAK;AAAA,IAC9B;AACA,WAAO,EAAE,MAAM,OAAO,MAAM,KAAK,OAAO,IAAI;AAAA,EAC9C;AAAA,EAEA,MAAM,OAAO,IAA2B;AACtC,UAAM,KAAK,YAAY,QAAQ,YAAY,IAAI,kBAAkB;AACjE,UAAM,KAAK,MAAM,OAAO,EAAE;AAAA,EAC5B;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/spectrum/index.js
CHANGED
|
@@ -38,8 +38,6 @@ import {
|
|
|
38
38
|
} from "./monitor-port.js";
|
|
39
39
|
import {
|
|
40
40
|
KEYS_MOVED,
|
|
41
|
-
MISMATCH,
|
|
42
|
-
mismatchBanner,
|
|
43
41
|
movedList,
|
|
44
42
|
movedNotice,
|
|
45
43
|
NoticesAdapter as NoticesAdapter2
|
|
@@ -76,7 +74,7 @@ function createAgentModel(connection, options = {}) {
|
|
|
76
74
|
sprinkles: new SprinkleAdapter(connection, report),
|
|
77
75
|
memory: new MemoryAdapter(connection, report),
|
|
78
76
|
changes: new ChangesAdapter(connection, report),
|
|
79
|
-
notices: new NoticesAdapter(connection.settings, report,
|
|
77
|
+
notices: new NoticesAdapter(connection.settings, report, options.notices),
|
|
80
78
|
monitor: new MonitorAdapter(
|
|
81
79
|
connection,
|
|
82
80
|
options.monitor?.extra ? { extra: options.monitor.extra } : {}
|
|
@@ -90,7 +88,6 @@ export {
|
|
|
90
88
|
ChangesAdapter2 as ChangesAdapter,
|
|
91
89
|
GuestAdapter2 as GuestAdapter,
|
|
92
90
|
KEYS_MOVED,
|
|
93
|
-
MISMATCH,
|
|
94
91
|
MemoryAdapter2 as MemoryAdapter,
|
|
95
92
|
MonitorAdapter2 as MonitorAdapter,
|
|
96
93
|
NOT_HERE,
|
|
@@ -108,7 +105,6 @@ export {
|
|
|
108
105
|
errorAction,
|
|
109
106
|
errorPart,
|
|
110
107
|
isBusy,
|
|
111
|
-
mismatchBanner,
|
|
112
108
|
monitorSnapshot,
|
|
113
109
|
movedList,
|
|
114
110
|
movedNotice,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/spectrum/index.ts"],
|
|
4
|
-
"sourcesContent": ["import type { MonitorSection } from '@ai-ecoverse/slicc-spectrum/ui';\nimport type { AgentConnection } from '../client.ts';\nimport type { GuestGates } from '../guests/seats.ts';\nimport { AgentAdapter } from './agent-port.ts';\nimport { ApprovalsAdapter, type HostApprovals } from './approvals-port.ts';\nimport { ChangesAdapter } from './changes-port.ts';\nimport { GuestAdapter, type GuestHub } from './guest-port.ts';\nimport { MemoryAdapter } from './memory-port.ts';\nimport { MonitorAdapter } from './monitor-port.ts';\nimport { type HostNotices, NoticesAdapter } from './notices-port.ts';\nimport { PageAdapter, type PageOptions } from './page-port.ts';\nimport { type Login, SettingsAdapter } from './settings-port.ts';\nimport { SprinkleAdapter } from './sprinkle-port.ts';\nimport { TrayAdapter } from './tray-port.ts';\n\nexport { AgentAdapter, CONE } from './agent-port.ts';\nexport {\n ApprovalsAdapter,\n type HostApprovals,\n NOT_HERE,\n shown as shownApproval,\n} from './approvals-port.ts';\nexport { ChangesAdapter, type ChangesEvents } from './changes-port.ts';\nexport {\n GuestAdapter,\n type GuestHub,\n NO_CONTROL,\n NO_HUB,\n NO_OWNER,\n} from './guest-port.ts';\nexport { MemoryAdapter } from './memory-port.ts';\nexport {\n assistant,\n errorAction,\n errorPart,\n isBusy,\n queued,\n textOf,\n toMessages,\n} from './messages.ts';\nexport {\n MonitorAdapter,\n type MonitorAdapterOptions,\n type MonitorInput,\n monitorSnapshot,\n} from './monitor-port.ts';\nexport {\n type HostNotices,\n KEYS_MOVED,\n
|
|
5
|
-
"mappings": "AAGA,SAAS,oBAAoB;AAC7B,SAAS,wBAA4C;AACrD,SAAS,sBAAsB;AAC/B,SAAS,oBAAmC;AAC5C,SAAS,qBAAqB;AAC9B,SAAS,sBAAsB;AAC/B,SAA2B,sBAAsB;AACjD,SAAS,mBAAqC;AAC9C,SAAqB,uBAAuB;AAC5C,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAE5B,SAAS,gBAAAA,eAAc,YAAY;AACnC;AAAA,EACE,oBAAAC;AAAA,EAEA;AAAA,EACS;AAAA,OACJ;AACP,SAAS,kBAAAC,uBAA0C;AACnD;AAAA,EACE,gBAAAC;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAAC,sBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE,kBAAAC;AAAA,EAGA;AAAA,OACK;AACP;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA
|
|
4
|
+
"sourcesContent": ["import type { MonitorSection } from '@ai-ecoverse/slicc-spectrum/ui';\nimport type { AgentConnection } from '../client.ts';\nimport type { GuestGates } from '../guests/seats.ts';\nimport { AgentAdapter } from './agent-port.ts';\nimport { ApprovalsAdapter, type HostApprovals } from './approvals-port.ts';\nimport { ChangesAdapter } from './changes-port.ts';\nimport { GuestAdapter, type GuestHub } from './guest-port.ts';\nimport { MemoryAdapter } from './memory-port.ts';\nimport { MonitorAdapter } from './monitor-port.ts';\nimport { type HostNotices, NoticesAdapter } from './notices-port.ts';\nimport { PageAdapter, type PageOptions } from './page-port.ts';\nimport { type Login, SettingsAdapter } from './settings-port.ts';\nimport { SprinkleAdapter } from './sprinkle-port.ts';\nimport { TrayAdapter } from './tray-port.ts';\n\nexport { AgentAdapter, CONE } from './agent-port.ts';\nexport {\n ApprovalsAdapter,\n type HostApprovals,\n NOT_HERE,\n shown as shownApproval,\n} from './approvals-port.ts';\nexport { ChangesAdapter, type ChangesEvents } from './changes-port.ts';\nexport {\n GuestAdapter,\n type GuestHub,\n NO_CONTROL,\n NO_HUB,\n NO_OWNER,\n} from './guest-port.ts';\nexport { MemoryAdapter } from './memory-port.ts';\nexport {\n assistant,\n errorAction,\n errorPart,\n isBusy,\n queued,\n textOf,\n toMessages,\n} from './messages.ts';\nexport {\n MonitorAdapter,\n type MonitorAdapterOptions,\n type MonitorInput,\n monitorSnapshot,\n} from './monitor-port.ts';\nexport {\n type HostNotices,\n KEYS_MOVED,\n movedList,\n movedNotice,\n NoticesAdapter,\n} from './notices-port.ts';\nexport {\n PageAdapter,\n type PageDocument,\n type PageOptions,\n type PageRun,\n type PageTarget,\n} from './page-port.ts';\nexport { type Login, SETTINGS_KEY, SettingsAdapter } from './settings-port.ts';\nexport { SprinkleAdapter } from './sprinkle-port.ts';\nexport { TrayAdapter } from './tray-port.ts';\n\nexport interface GuestSeatShown {\n id: string;\n label: string;\n agentId: string;\n expiresAt: number | null;\n gates: GuestGates;\n}\n\nfunction seatOf(connection: AgentConnection): { seat?: GuestSeatShown } {\n const guest = connection.guest;\n if (!guest) return {};\n const { id, label, agentId, expiresAt, gates } = guest;\n return { seat: { id, label, agentId, expiresAt, gates: { ...gates } } };\n}\n\nexport function createAgentModel(\n connection: AgentConnection,\n options: {\n storage?: Pick<Storage, 'getItem' | 'setItem'> | null;\n login?: Login;\n monitor?: { extra?: () => readonly MonitorSection[] };\n page?: PageOptions;\n guests?: GuestHub;\n approvals?: HostApprovals;\n notices?: HostNotices;\n } = {}\n): {\n agent: AgentAdapter;\n approvals: ApprovalsAdapter;\n settings: SettingsAdapter;\n tray: TrayAdapter;\n sprinkles: SprinkleAdapter;\n memory: MemoryAdapter;\n changes: ChangesAdapter;\n monitor: MonitorAdapter;\n notices: NoticesAdapter;\n page: PageAdapter | null;\n guests: GuestAdapter;\n seat?: GuestSeatShown;\n} {\n const agent = new AgentAdapter(connection);\n const report = (text: string) => agent.notify(text);\n const run = options.page?.run;\n return {\n agent,\n guests: new GuestAdapter(connection, options.guests ?? null),\n ...seatOf(connection),\n approvals: new ApprovalsAdapter(connection, options.approvals),\n page: options.page && run ? new PageAdapter(connection, agent, { ...options.page, run }) : null,\n settings: new SettingsAdapter(\n connection.settings,\n agent,\n options.storage ?? null,\n options.login ?? null\n ),\n tray: new TrayAdapter(connection.settings),\n sprinkles: new SprinkleAdapter(connection, report),\n memory: new MemoryAdapter(connection, report),\n changes: new ChangesAdapter(connection, report),\n notices: new NoticesAdapter(connection.settings, report, options.notices),\n monitor: new MonitorAdapter(\n connection,\n options.monitor?.extra ? { extra: options.monitor.extra } : {}\n ),\n };\n}\n"],
|
|
5
|
+
"mappings": "AAGA,SAAS,oBAAoB;AAC7B,SAAS,wBAA4C;AACrD,SAAS,sBAAsB;AAC/B,SAAS,oBAAmC;AAC5C,SAAS,qBAAqB;AAC9B,SAAS,sBAAsB;AAC/B,SAA2B,sBAAsB;AACjD,SAAS,mBAAqC;AAC9C,SAAqB,uBAAuB;AAC5C,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAE5B,SAAS,gBAAAA,eAAc,YAAY;AACnC;AAAA,EACE,oBAAAC;AAAA,EAEA;AAAA,EACS;AAAA,OACJ;AACP,SAAS,kBAAAC,uBAA0C;AACnD;AAAA,EACE,gBAAAC;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAAC,sBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE,kBAAAC;AAAA,EAGA;AAAA,OACK;AACP;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAAC;AAAA,OACK;AACP;AAAA,EACE,eAAAC;AAAA,OAKK;AACP,SAAqB,cAAc,mBAAAC,wBAAuB;AAC1D,SAAS,mBAAAC,wBAAuB;AAChC,SAAS,eAAAC,oBAAmB;AAU5B,SAAS,OAAO,YAAwD;AACtE,QAAM,QAAQ,WAAW;AACzB,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,QAAM,EAAE,IAAI,OAAO,SAAS,WAAW,MAAM,IAAI;AACjD,SAAO,EAAE,MAAM,EAAE,IAAI,OAAO,SAAS,WAAW,OAAO,EAAE,GAAG,MAAM,EAAE,EAAE;AACxE;AAEO,SAAS,iBACd,YACA,UAQI,CAAC,GAcL;AACA,QAAM,QAAQ,IAAI,aAAa,UAAU;AACzC,QAAM,SAAS,CAAC,SAAiB,MAAM,OAAO,IAAI;AAClD,QAAM,MAAM,QAAQ,MAAM;AAC1B,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,IAAI,aAAa,YAAY,QAAQ,UAAU,IAAI;AAAA,IAC3D,GAAG,OAAO,UAAU;AAAA,IACpB,WAAW,IAAI,iBAAiB,YAAY,QAAQ,SAAS;AAAA,IAC7D,MAAM,QAAQ,QAAQ,MAAM,IAAI,YAAY,YAAY,OAAO,EAAE,GAAG,QAAQ,MAAM,IAAI,CAAC,IAAI;AAAA,IAC3F,UAAU,IAAI;AAAA,MACZ,WAAW;AAAA,MACX;AAAA,MACA,QAAQ,WAAW;AAAA,MACnB,QAAQ,SAAS;AAAA,IACnB;AAAA,IACA,MAAM,IAAI,YAAY,WAAW,QAAQ;AAAA,IACzC,WAAW,IAAI,gBAAgB,YAAY,MAAM;AAAA,IACjD,QAAQ,IAAI,cAAc,YAAY,MAAM;AAAA,IAC5C,SAAS,IAAI,eAAe,YAAY,MAAM;AAAA,IAC9C,SAAS,IAAI,eAAe,WAAW,UAAU,QAAQ,QAAQ,OAAO;AAAA,IACxE,SAAS,IAAI;AAAA,MACX;AAAA,MACA,QAAQ,SAAS,QAAQ,EAAE,OAAO,QAAQ,QAAQ,MAAM,IAAI,CAAC;AAAA,IAC/D;AAAA,EACF;AACF;",
|
|
6
6
|
"names": ["AgentAdapter", "ApprovalsAdapter", "ChangesAdapter", "GuestAdapter", "MemoryAdapter", "MonitorAdapter", "NoticesAdapter", "PageAdapter", "SettingsAdapter", "SprinkleAdapter", "TrayAdapter"]
|
|
7
7
|
}
|
|
@@ -2,17 +2,6 @@ import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context";
|
|
|
2
2
|
import { attempt } from "./attempt.js";
|
|
3
3
|
import { Emitter } from "./emitter.js";
|
|
4
4
|
const KEYS_MOVED = "keys-moved";
|
|
5
|
-
const MISMATCH = "agent-mismatch";
|
|
6
|
-
function mismatchBanner(text) {
|
|
7
|
-
return {
|
|
8
|
-
id: MISMATCH,
|
|
9
|
-
tone: "warning",
|
|
10
|
-
title: "This tab can't follow that SLICC",
|
|
11
|
-
body: text,
|
|
12
|
-
actions: [],
|
|
13
|
-
dismissible: false
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
5
|
function servers(names, lead) {
|
|
17
6
|
if (names.length > 1) return `MCP servers: ${names.join(", ")}`;
|
|
18
7
|
return `${lead ? "the" : "and the"} MCP server ${names[0]}`;
|
|
@@ -36,14 +25,12 @@ function movedNotice(accounts) {
|
|
|
36
25
|
class NoticesAdapter extends Emitter {
|
|
37
26
|
#settings;
|
|
38
27
|
#report;
|
|
39
|
-
#mismatch;
|
|
40
28
|
#host;
|
|
41
29
|
#hidden = false;
|
|
42
|
-
constructor(settings, report,
|
|
30
|
+
constructor(settings, report, host) {
|
|
43
31
|
super();
|
|
44
32
|
this.#settings = settings;
|
|
45
33
|
this.#report = report;
|
|
46
|
-
this.#mismatch = mismatch ? [mismatchBanner(mismatch)] : [];
|
|
47
34
|
this.#host = host;
|
|
48
35
|
settings.state.subscribe(() => this.emit("notices", this.list()));
|
|
49
36
|
host?.on("notices", () => this.emit("notices", this.list()));
|
|
@@ -53,7 +40,7 @@ class NoticesAdapter extends Emitter {
|
|
|
53
40
|
}
|
|
54
41
|
#agent() {
|
|
55
42
|
const moved = this.#settings.state.value?.moved;
|
|
56
|
-
return
|
|
43
|
+
return moved?.length && !this.#hidden ? [movedNotice(moved)] : [];
|
|
57
44
|
}
|
|
58
45
|
#hosts(id) {
|
|
59
46
|
return this.#host?.list().find((notice) => notice.id === id);
|
|
@@ -75,9 +62,7 @@ class NoticesAdapter extends Emitter {
|
|
|
75
62
|
}
|
|
76
63
|
export {
|
|
77
64
|
KEYS_MOVED,
|
|
78
|
-
MISMATCH,
|
|
79
65
|
NoticesAdapter,
|
|
80
|
-
mismatchBanner,
|
|
81
66
|
movedList,
|
|
82
67
|
movedNotice
|
|
83
68
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/spectrum/notices-port.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Notice, NoticesPort } from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { MovedName } from '../secrets/legacy.ts';\nimport type { AgentSettings } from '../services.ts';\nimport { attempt, type Report } from './attempt.ts';\nimport { Emitter } from './emitter.ts';\n\nexport const KEYS_MOVED = 'keys-moved';\n\
|
|
5
|
-
"mappings": "AACA,SAAS,0BAA0B;AAGnC,SAAS,eAA4B;AACrC,SAAS,eAAe;AAEjB,MAAM,aAAa;
|
|
4
|
+
"sourcesContent": ["import type { Notice, NoticesPort } from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { MovedName } from '../secrets/legacy.ts';\nimport type { AgentSettings } from '../services.ts';\nimport { attempt, type Report } from './attempt.ts';\nimport { Emitter } from './emitter.ts';\n\nexport const KEYS_MOVED = 'keys-moved';\n\nfunction servers(names: readonly string[], lead: boolean): string {\n if (names.length > 1) return `MCP servers: ${names.join(', ')}`;\n return `${lead ? 'the' : 'and the'} MCP server ${names[0]}`;\n}\n\nexport function movedList(accounts: readonly MovedName[]): string {\n const models = accounts.filter((name) => name.kind === 'model').map((name) => name.label);\n const mcp = accounts.filter((name) => name.kind === 'mcp').map((name) => name.label);\n if (!mcp.length) return models.join(', ');\n if (!models.length) return servers(mcp, true);\n return `${models.join(', ')}${mcp.length > 1 ? '; ' : ', '}${servers(mcp, false)}`;\n}\n\nexport function movedNotice(accounts: readonly MovedName[]): Notice {\n return {\n id: KEYS_MOVED,\n tone: 'info',\n title: \"Your keys moved to seven's vault.\",\n body: `Add them again in Settings \u203A Accounts: ${movedList(accounts)}.`,\n actions: [],\n };\n}\n\nexport type HostNotices = Pick<NoticesPort, 'list' | 'act' | 'dismiss' | 'on'>;\n\nexport class NoticesAdapter extends Emitter<{ notices: readonly Notice[] }> implements NoticesPort {\n readonly #settings: AgentSettings;\n readonly #report: Report;\n readonly #host: HostNotices | undefined;\n #hidden = false;\n\n constructor(settings: AgentSettings, report: Report, host?: HostNotices) {\n super();\n this.#settings = settings;\n this.#report = report;\n this.#host = host;\n settings.state.subscribe(() => this.emit('notices', this.list()));\n host?.on('notices', () => this.emit('notices', this.list()));\n }\n\n list(): readonly Notice[] {\n return [...(this.#host?.list() ?? []), ...this.#agent()];\n }\n\n #agent(): readonly Notice[] {\n const moved = this.#settings.state.value?.moved;\n return moved?.length && !this.#hidden ? [movedNotice(moved)] : [];\n }\n\n #hosts(id: string): Notice | undefined {\n return this.#host?.list().find((notice) => notice.id === id);\n }\n\n async act(id: string, action: string): Promise<void> {\n if (this.#hosts(id)) await this.#host?.act(id, action);\n }\n\n dismiss(id: string): void {\n const hosted = this.#hosts(id);\n if (hosted) {\n if (hosted.dismissible !== false) this.#host?.dismiss(id);\n return;\n }\n if (id !== KEYS_MOVED) return;\n this.#hidden = true;\n this.emit('notices', this.list());\n attempt(this.#settings.dismissMoved(BACKGROUND_CONTEXT), 'dismiss the notice', this.#report);\n }\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,0BAA0B;AAGnC,SAAS,eAA4B;AACrC,SAAS,eAAe;AAEjB,MAAM,aAAa;AAE1B,SAAS,QAAQ,OAA0B,MAAuB;AAChE,MAAI,MAAM,SAAS,EAAG,QAAO,gBAAgB,MAAM,KAAK,IAAI,CAAC;AAC7D,SAAO,GAAG,OAAO,QAAQ,SAAS,eAAe,MAAM,CAAC,CAAC;AAC3D;AAEO,SAAS,UAAU,UAAwC;AAChE,QAAM,SAAS,SAAS,OAAO,CAAC,SAAS,KAAK,SAAS,OAAO,EAAE,IAAI,CAAC,SAAS,KAAK,KAAK;AACxF,QAAM,MAAM,SAAS,OAAO,CAAC,SAAS,KAAK,SAAS,KAAK,EAAE,IAAI,CAAC,SAAS,KAAK,KAAK;AACnF,MAAI,CAAC,IAAI,OAAQ,QAAO,OAAO,KAAK,IAAI;AACxC,MAAI,CAAC,OAAO,OAAQ,QAAO,QAAQ,KAAK,IAAI;AAC5C,SAAO,GAAG,OAAO,KAAK,IAAI,CAAC,GAAG,IAAI,SAAS,IAAI,OAAO,IAAI,GAAG,QAAQ,KAAK,KAAK,CAAC;AAClF;AAEO,SAAS,YAAY,UAAwC;AAClE,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,OAAO;AAAA,IACP,MAAM,+CAA0C,UAAU,QAAQ,CAAC;AAAA,IACnE,SAAS,CAAC;AAAA,EACZ;AACF;AAIO,MAAM,uBAAuB,QAA+D;AAAA,EACxF;AAAA,EACA;AAAA,EACA;AAAA,EACT,UAAU;AAAA,EAEV,YAAY,UAAyB,QAAgB,MAAoB;AACvE,UAAM;AACN,SAAK,YAAY;AACjB,SAAK,UAAU;AACf,SAAK,QAAQ;AACb,aAAS,MAAM,UAAU,MAAM,KAAK,KAAK,WAAW,KAAK,KAAK,CAAC,CAAC;AAChE,UAAM,GAAG,WAAW,MAAM,KAAK,KAAK,WAAW,KAAK,KAAK,CAAC,CAAC;AAAA,EAC7D;AAAA,EAEA,OAA0B;AACxB,WAAO,CAAC,GAAI,KAAK,OAAO,KAAK,KAAK,CAAC,GAAI,GAAG,KAAK,OAAO,CAAC;AAAA,EACzD;AAAA,EAEA,SAA4B;AAC1B,UAAM,QAAQ,KAAK,UAAU,MAAM,OAAO;AAC1C,WAAO,OAAO,UAAU,CAAC,KAAK,UAAU,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC;AAAA,EAClE;AAAA,EAEA,OAAO,IAAgC;AACrC,WAAO,KAAK,OAAO,KAAK,EAAE,KAAK,CAAC,WAAW,OAAO,OAAO,EAAE;AAAA,EAC7D;AAAA,EAEA,MAAM,IAAI,IAAY,QAA+B;AACnD,QAAI,KAAK,OAAO,EAAE,EAAG,OAAM,KAAK,OAAO,IAAI,IAAI,MAAM;AAAA,EACvD;AAAA,EAEA,QAAQ,IAAkB;AACxB,UAAM,SAAS,KAAK,OAAO,EAAE;AAC7B,QAAI,QAAQ;AACV,UAAI,OAAO,gBAAgB,MAAO,MAAK,OAAO,QAAQ,EAAE;AACxD;AAAA,IACF;AACA,QAAI,OAAO,WAAY;AACvB,SAAK,UAAU;AACf,SAAK,KAAK,WAAW,KAAK,KAAK,CAAC;AAChC,YAAQ,KAAK,UAAU,aAAa,kBAAkB,GAAG,sBAAsB,KAAK,OAAO;AAAA,EAC7F;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/types/client.d.ts
CHANGED
|
@@ -38,7 +38,6 @@ export interface AgentConnection {
|
|
|
38
38
|
readonly remote?: AgentRemote;
|
|
39
39
|
readonly pages?: AgentPages;
|
|
40
40
|
readonly closed: Promise<Error | undefined>;
|
|
41
|
-
readonly mismatch?: string;
|
|
42
41
|
readonly readOnly?: boolean;
|
|
43
42
|
prompt(text: string, whenBusy?: SendMode): Promise<string>;
|
|
44
43
|
webhook(name: string, delivery: {
|
|
@@ -9,4 +9,4 @@ export interface GuestConnection extends AgentConnection {
|
|
|
9
9
|
readonly guest: GuestShown;
|
|
10
10
|
propose(request: ProposeRequest): Promise<Proposed>;
|
|
11
11
|
}
|
|
12
|
-
export declare function connectGuest(endpoint: PortEndpoint): Promise<GuestConnection
|
|
12
|
+
export declare function connectGuest(endpoint: PortEndpoint): Promise<GuestConnection>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -21,5 +21,5 @@ export { BEDROCK, createAgentSettings, createSliccModels, DEFAULT_MODEL, DEFAULT
|
|
|
21
21
|
export { AGENT_DIRECTORY, type OpfsSqliteOptions, openMemorySqliteStorage, openOpfsSqliteStorage, WasmSqliteDatabase, } from './sqlite.ts';
|
|
22
22
|
export { type SystemFacts, systemSection } from './system.ts';
|
|
23
23
|
export { UPLOADS, type Uploads, upload } from './uploads.ts';
|
|
24
|
-
export {
|
|
24
|
+
export { type PortEndpoint, PortLink } from './wire.ts';
|
|
25
25
|
export { type KernelPorts, kernelPort, kernelPorts, serveConnections, type WorkerScope, } from './worker.ts';
|
|
@@ -5,7 +5,6 @@ import type { Command } from '../services.ts';
|
|
|
5
5
|
import { Emitter } from './emitter.ts';
|
|
6
6
|
export declare const CONE = "cone";
|
|
7
7
|
export declare function slashCommand({ kind, ...command }: Command): SlashCommand;
|
|
8
|
-
export declare const WATCH_ONLY = "Watch only.";
|
|
9
8
|
export type AgentHold = VaultHold;
|
|
10
9
|
export type AgentAdapterEvents = AgentEvents & {
|
|
11
10
|
hold: AgentHold | null;
|
|
@@ -16,7 +15,6 @@ export declare class AgentAdapter extends Emitter<AgentAdapterEvents> implements
|
|
|
16
15
|
notify(text: string, agentId?: string): void;
|
|
17
16
|
ready(): Promise<void>;
|
|
18
17
|
hold(): AgentHold | null;
|
|
19
|
-
readOnly(): string | null;
|
|
20
18
|
list(): readonly Agent[];
|
|
21
19
|
active(): string;
|
|
22
20
|
select(id: string): void;
|
|
@@ -19,7 +19,7 @@ export { GuestAdapter, type GuestHub, NO_CONTROL, NO_HUB, NO_OWNER, } from './gu
|
|
|
19
19
|
export { MemoryAdapter } from './memory-port.ts';
|
|
20
20
|
export { assistant, errorAction, errorPart, isBusy, queued, textOf, toMessages, } from './messages.ts';
|
|
21
21
|
export { MonitorAdapter, type MonitorAdapterOptions, type MonitorInput, monitorSnapshot, } from './monitor-port.ts';
|
|
22
|
-
export { type HostNotices, KEYS_MOVED,
|
|
22
|
+
export { type HostNotices, KEYS_MOVED, movedList, movedNotice, NoticesAdapter, } from './notices-port.ts';
|
|
23
23
|
export { PageAdapter, type PageDocument, type PageOptions, type PageRun, type PageTarget, } from './page-port.ts';
|
|
24
24
|
export { type Login, SETTINGS_KEY, SettingsAdapter } from './settings-port.ts';
|
|
25
25
|
export { SprinkleAdapter } from './sprinkle-port.ts';
|
|
@@ -4,8 +4,6 @@ import type { AgentSettings } from '../services.ts';
|
|
|
4
4
|
import { type Report } from './attempt.ts';
|
|
5
5
|
import { Emitter } from './emitter.ts';
|
|
6
6
|
export declare const KEYS_MOVED = "keys-moved";
|
|
7
|
-
export declare const MISMATCH = "agent-mismatch";
|
|
8
|
-
export declare function mismatchBanner(text: string): Notice;
|
|
9
7
|
export declare function movedList(accounts: readonly MovedName[]): string;
|
|
10
8
|
export declare function movedNotice(accounts: readonly MovedName[]): Notice;
|
|
11
9
|
export type HostNotices = Pick<NoticesPort, 'list' | 'act' | 'dismiss' | 'on'>;
|
|
@@ -13,7 +11,7 @@ export declare class NoticesAdapter extends Emitter<{
|
|
|
13
11
|
notices: readonly Notice[];
|
|
14
12
|
}> implements NoticesPort {
|
|
15
13
|
#private;
|
|
16
|
-
constructor(settings: AgentSettings, report: Report,
|
|
14
|
+
constructor(settings: AgentSettings, report: Report, host?: HostNotices);
|
|
17
15
|
list(): readonly Notice[];
|
|
18
16
|
act(id: string, action: string): Promise<void>;
|
|
19
17
|
dismiss(id: string): void;
|
package/dist/types/wire.d.ts
CHANGED
|
@@ -11,13 +11,6 @@ export type Frame = {
|
|
|
11
11
|
} | {
|
|
12
12
|
close: true;
|
|
13
13
|
} | Uint8Array;
|
|
14
|
-
export declare const LINK_PROTOCOL = 2;
|
|
15
|
-
export interface Greeting {
|
|
16
|
-
protocol: number;
|
|
17
|
-
serverId: string;
|
|
18
|
-
}
|
|
19
|
-
export declare const greeting: (serverId: string) => string;
|
|
20
|
-
export declare function greeted(hello: string): Greeting;
|
|
21
14
|
export declare class PortLink implements Link {
|
|
22
15
|
#private;
|
|
23
16
|
readonly hello: Promise<string>;
|
package/dist/wire.js
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
const LINK_PROTOCOL = 2;
|
|
2
|
-
const GREETING = /^slicc-agent-link\/(\d+) (.+)$/;
|
|
3
|
-
const greeting = (serverId) => `slicc-agent-link/${LINK_PROTOCOL} ${serverId}`;
|
|
4
|
-
function greeted(hello) {
|
|
5
|
-
const found = GREETING.exec(hello);
|
|
6
|
-
return found ? { protocol: Number(found[1]), serverId: found[2] } : { protocol: 1, serverId: hello };
|
|
7
|
-
}
|
|
8
1
|
const encoder = new TextEncoder();
|
|
9
2
|
const decoder = new TextDecoder();
|
|
10
3
|
function parse(chunk) {
|
|
@@ -45,7 +38,7 @@ class PortLink {
|
|
|
45
38
|
return this.#closed;
|
|
46
39
|
}
|
|
47
40
|
greet(serverId) {
|
|
48
|
-
this.#endpoint.postMessage({ hello:
|
|
41
|
+
this.#endpoint.postMessage({ hello: serverId });
|
|
49
42
|
}
|
|
50
43
|
send(frame) {
|
|
51
44
|
if (this.#closed) return;
|
|
@@ -98,9 +91,6 @@ class PortLink {
|
|
|
98
91
|
}
|
|
99
92
|
}
|
|
100
93
|
export {
|
|
101
|
-
|
|
102
|
-
PortLink,
|
|
103
|
-
greeted,
|
|
104
|
-
greeting
|
|
94
|
+
PortLink
|
|
105
95
|
};
|
|
106
96
|
//# sourceMappingURL=wire.js.map
|
package/dist/wire.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/wire.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Frame as ChordFrame, Link } from '@earendil-works/chord';\n\nexport interface PortEndpoint {\n postMessage(message: unknown, transfer?: Transferable[]): void;\n addEventListener(type: 'message', listener: (event: MessageEvent) => void): void;\n addEventListener(\n type: 'close' | 'messageerror' | 'error',\n listener: (event: Event) => void\n ): void;\n start?(): void;\n close?(): void;\n}\n\nexport type Frame = { hello: string } | { close: true } | Uint8Array;\n\
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import type { Frame as ChordFrame, Link } from '@earendil-works/chord';\n\nexport interface PortEndpoint {\n postMessage(message: unknown, transfer?: Transferable[]): void;\n addEventListener(type: 'message', listener: (event: MessageEvent) => void): void;\n addEventListener(\n type: 'close' | 'messageerror' | 'error',\n listener: (event: Event) => void\n ): void;\n start?(): void;\n close?(): void;\n}\n\nexport type Frame = { hello: string } | { close: true } | Uint8Array;\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\nfunction parse(chunk: Uint8Array): ChordFrame {\n const frame = JSON.parse(decoder.decode(chunk)) as { t?: unknown } | null;\n if (frame === null || typeof frame !== 'object' || typeof frame.t !== 'string')\n throw new TypeError('not a chord frame');\n return frame as ChordFrame;\n}\n\nexport class PortLink implements Link {\n readonly hello: Promise<string>;\n readonly ended: Promise<Error | undefined>;\n readonly #endpoint: PortEndpoint;\n readonly #queue: Uint8Array[] = [];\n readonly #closers = new Set<(reason: string) => void>();\n #handler: ((frame: ChordFrame) => void) | undefined;\n #closed = false;\n #greet!: (hello: string) => void;\n #refuse!: (error: Error) => void;\n #finish!: (reason: Error | undefined) => void;\n\n constructor(endpoint: PortEndpoint) {\n this.#endpoint = endpoint;\n this.hello = new Promise((greet, refuse) => {\n this.#greet = greet;\n this.#refuse = refuse;\n });\n this.hello.catch(() => undefined);\n this.ended = new Promise((finish) => {\n this.#finish = finish;\n });\n endpoint.addEventListener('message', ({ data }) => this.#receive(data as Frame));\n const failed = (event: Event) => this.#end(`agent port ${event.type}`, true);\n endpoint.addEventListener('messageerror', failed);\n endpoint.addEventListener('error', failed);\n endpoint.addEventListener('close', () => this.#end('peer closed', false));\n endpoint.start?.();\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n\n greet(serverId: string): void {\n this.#endpoint.postMessage({ hello: serverId } satisfies Frame);\n }\n\n send(frame: ChordFrame): void {\n if (this.#closed) return;\n const bytes = encoder.encode(JSON.stringify(frame));\n this.#endpoint.postMessage(bytes, [bytes.buffer]);\n }\n\n receive(handler: (frame: ChordFrame) => void): void {\n this.#handler = handler;\n for (const chunk of this.#queue.splice(0)) this.#deliver(chunk);\n }\n\n onClose(handler: (reason: string) => void): void {\n if (this.#closed) handler('closed');\n else this.#closers.add(handler);\n }\n\n close(reason = 'closed'): void {\n if (this.#closed) return;\n this.send({ t: 'bye', reason });\n this.#endpoint.postMessage({ close: true } satisfies Frame);\n this.#end(reason, false);\n }\n\n #receive(frame: Frame): void {\n if (this.#closed) return;\n if (frame instanceof Uint8Array) {\n if (this.#handler) this.#deliver(frame);\n else this.#queue.push(frame);\n } else if ('hello' in frame) this.#greet(frame.hello);\n else this.#end('peer closed', false);\n }\n\n #deliver(chunk: Uint8Array): void {\n let frame: ChordFrame;\n try {\n frame = parse(chunk);\n } catch {\n this.close('protocol error');\n return;\n }\n if (frame.t === 'bye') this.#end(frame.reason ?? 'peer closed', false);\n else this.#handler?.(frame);\n }\n\n #end(reason: string, failed: boolean): void {\n if (this.#closed) return;\n this.#closed = true;\n this.#queue.length = 0;\n this.#endpoint.close?.();\n const error = new Error(reason);\n this.#refuse(new Error(`agent port closed before hello: ${reason}`));\n this.#finish(failed ? error : undefined);\n for (const handler of [...this.#closers]) handler(reason);\n this.#closers.clear();\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-ecoverse/slicc-agent",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.4.0",
|
|
4
4
|
"description": "SLICC's agent core on pi durable: an agent worker, session storage, remoting and pi extensions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"@ai-ecoverse/slicc-kernel": "1.100.3",
|
|
66
66
|
"@ai-ecoverse/slicc-scrub": "1.0.0",
|
|
67
67
|
"@ai-ecoverse/slicc-shared-web": "1.21.0",
|
|
68
|
-
"@ai-ecoverse/slicc-spectrum": "1.
|
|
68
|
+
"@ai-ecoverse/slicc-spectrum": "1.80.0",
|
|
69
69
|
"@ai-ecoverse/wasm-bash": "5.3.0-18",
|
|
70
70
|
"@ai-ecoverse/wasm-coreutils": "9.12.0-7",
|
|
71
71
|
"@ai-ecoverse/wasm-git": "2.55.0-15",
|
|
@@ -77,7 +77,6 @@
|
|
|
77
77
|
"monocart-coverage-reports": "2.13.2",
|
|
78
78
|
"playwright-core": "1.64.0",
|
|
79
79
|
"semantic-release": "25.0.9",
|
|
80
|
-
"slicc-agent-4": "npm:@ai-ecoverse/slicc-agent@4.3.5",
|
|
81
80
|
"typescript": "7.0.2"
|
|
82
81
|
},
|
|
83
82
|
"dependencies": {
|
package/dist/mismatch.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { replicatedState } from "@earendil-works/chord";
|
|
2
|
-
import { LINK_PROTOCOL } from "./wire.js";
|
|
3
|
-
function mismatchNotice(protocol) {
|
|
4
|
-
const version = protocol < LINK_PROTOCOL ? "an older" : protocol > LINK_PROTOCOL ? "a newer" : "another";
|
|
5
|
-
const update = protocol < LINK_PROTOCOL ? "Update that SLICC" : protocol > LINK_PROTOCOL ? "Update this SLICC" : "Update both SLICCs";
|
|
6
|
-
return `That SLICC runs ${version} version of the agent than this one, so this tab can't follow it. ${update}, then reload this page.`;
|
|
7
|
-
}
|
|
8
|
-
function mismatched(serverId, protocol) {
|
|
9
|
-
const notice = mismatchNotice(protocol);
|
|
10
|
-
const refuse = () => Promise.reject(Object.assign(new Error(notice), { code: "EPROTO" }));
|
|
11
|
-
const control = new Proxy({}, { get: () => refuse });
|
|
12
|
-
let ended;
|
|
13
|
-
const closed = new Promise((resolve) => {
|
|
14
|
-
ended = resolve;
|
|
15
|
-
});
|
|
16
|
-
return {
|
|
17
|
-
serverId,
|
|
18
|
-
mismatch: notice,
|
|
19
|
-
control,
|
|
20
|
-
transcript: replicatedState({ conversation: {}, entries: [], docs: {} }),
|
|
21
|
-
deliveries: replicatedState({}),
|
|
22
|
-
settings: {
|
|
23
|
-
state: replicatedState({ models: [], accounts: [] }),
|
|
24
|
-
connect: refuse,
|
|
25
|
-
disconnect: refuse,
|
|
26
|
-
signIn: refuse,
|
|
27
|
-
dismissMoved: refuse
|
|
28
|
-
},
|
|
29
|
-
closed,
|
|
30
|
-
prompt: refuse,
|
|
31
|
-
webhook: refuse,
|
|
32
|
-
async close() {
|
|
33
|
-
ended(void 0);
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
export {
|
|
38
|
-
mismatchNotice,
|
|
39
|
-
mismatched
|
|
40
|
-
};
|
|
41
|
-
//# sourceMappingURL=mismatch.js.map
|
package/dist/mismatch.js.map
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/mismatch.ts"],
|
|
4
|
-
"sourcesContent": ["import { replicatedState } from '@earendil-works/chord';\nimport type { AgentConnection } from './client.ts';\nimport { LINK_PROTOCOL } from './wire.ts';\n\nexport function mismatchNotice(protocol: number): string {\n const version =\n protocol < LINK_PROTOCOL ? 'an older' : protocol > LINK_PROTOCOL ? 'a newer' : 'another';\n const update =\n protocol < LINK_PROTOCOL\n ? 'Update that SLICC'\n : protocol > LINK_PROTOCOL\n ? 'Update this SLICC'\n : 'Update both SLICCs';\n return `That SLICC runs ${version} version of the agent than this one, so this tab can't follow it. ${update}, then reload this page.`;\n}\n\nexport function mismatched(serverId: string, protocol: number): AgentConnection {\n const notice = mismatchNotice(protocol);\n const refuse = () => Promise.reject(Object.assign(new Error(notice), { code: 'EPROTO' }));\n const control = new Proxy({}, { get: () => refuse }) as AgentConnection['control'];\n let ended!: (reason: undefined) => void;\n const closed = new Promise<undefined>((resolve) => {\n ended = resolve;\n });\n return {\n serverId,\n mismatch: notice,\n control,\n transcript: replicatedState({ conversation: {} as never, entries: [], docs: {} }),\n deliveries: replicatedState({}),\n settings: {\n state: replicatedState({ models: [], accounts: [] }),\n connect: refuse,\n disconnect: refuse,\n signIn: refuse,\n dismissMoved: refuse,\n },\n closed,\n prompt: refuse,\n webhook: refuse,\n async close() {\n ended(undefined);\n },\n };\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,uBAAuB;AAEhC,SAAS,qBAAqB;AAEvB,SAAS,eAAe,UAA0B;AACvD,QAAM,UACJ,WAAW,gBAAgB,aAAa,WAAW,gBAAgB,YAAY;AACjF,QAAM,SACJ,WAAW,gBACP,sBACA,WAAW,gBACT,sBACA;AACR,SAAO,mBAAmB,OAAO,qEAAqE,MAAM;AAC9G;AAEO,SAAS,WAAW,UAAkB,UAAmC;AAC9E,QAAM,SAAS,eAAe,QAAQ;AACtC,QAAM,SAAS,MAAM,QAAQ,OAAO,OAAO,OAAO,IAAI,MAAM,MAAM,GAAG,EAAE,MAAM,SAAS,CAAC,CAAC;AACxF,QAAM,UAAU,IAAI,MAAM,CAAC,GAAG,EAAE,KAAK,MAAM,OAAO,CAAC;AACnD,MAAI;AACJ,QAAM,SAAS,IAAI,QAAmB,CAAC,YAAY;AACjD,YAAQ;AAAA,EACV,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA,UAAU;AAAA,IACV;AAAA,IACA,YAAY,gBAAgB,EAAE,cAAc,CAAC,GAAY,SAAS,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC;AAAA,IAChF,YAAY,gBAAgB,CAAC,CAAC;AAAA,IAC9B,UAAU;AAAA,MACR,OAAO,gBAAgB,EAAE,QAAQ,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC;AAAA,MACnD,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,cAAc;AAAA,IAChB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,MAAM,QAAQ;AACZ,YAAM,MAAS;AAAA,IACjB;AAAA,EACF;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
package/dist/types/mismatch.d.ts
DELETED