@ai-ecoverse/slicc-agent 4.3.0 → 4.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/dist/client.js +12 -3
- package/dist/client.js.map +2 -2
- package/dist/host.js +3 -1
- package/dist/host.js.map +2 -2
- package/dist/main.js +17 -5
- package/dist/main.js.map +2 -2
- package/dist/mismatch.js +36 -0
- package/dist/mismatch.js.map +7 -0
- package/dist/readonly.js +7 -1
- package/dist/readonly.js.map +2 -2
- package/dist/secrets/legacy.js +112 -0
- package/dist/secrets/legacy.js.map +7 -0
- package/dist/services.js.map +2 -2
- package/dist/settings.js +8 -2
- package/dist/settings.js.map +2 -2
- package/dist/spectrum/agent-port.js +26 -8
- package/dist/spectrum/agent-port.js.map +2 -2
- package/dist/spectrum/index.js +6 -0
- package/dist/spectrum/index.js.map +3 -3
- package/dist/spectrum/messages.js +18 -4
- package/dist/spectrum/messages.js.map +2 -2
- package/dist/spectrum/notices-port.js +42 -0
- package/dist/spectrum/notices-port.js.map +7 -0
- package/dist/titles/cluster.js +61 -0
- package/dist/titles/cluster.js.map +7 -0
- package/dist/titles/labels.js +70 -59
- package/dist/titles/labels.js.map +2 -2
- package/dist/types/client.d.ts +1 -0
- package/dist/types/mismatch.d.ts +3 -0
- package/dist/types/secrets/legacy.d.ts +36 -0
- package/dist/types/services.d.ts +2 -0
- package/dist/types/settings.d.ts +2 -0
- package/dist/types/spectrum/index.d.ts +3 -0
- package/dist/types/spectrum/messages.d.ts +2 -0
- package/dist/types/spectrum/notices-port.d.ts +15 -0
- package/dist/types/titles/cluster.d.ts +15 -0
- package/dist/types/titles/labels.d.ts +3 -9
- package/dist/types/wire.d.ts +6 -0
- package/dist/wire.js +8 -0
- package/dist/wire.js.map +2 -2
- package/package.json +4 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/titles/labels.ts"],
|
|
4
|
-
"sourcesContent": ["import { type Context, type ReplicatedState, replicatedState } from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { AssistantMessage, Usage } from '@earendil-works/pi-ai';\nimport {\n type ConversationId,\n type ConversationView,\n defineDoc,\n type EntryRecord,\n type Harness,\n type Tx,\n UsageDoc,\n} from '@earendil-works/pi-durable';\nimport { answerText } from '../agent.ts';\nimport type { Agents } from '../agents.ts';\nimport type { VaultState } from '../secrets/vault.ts';\nimport { vaultHold } from '../secrets/view.ts';\nimport { type Labeler, scrubbed } from './generate.ts';\nimport { labelKey, shownLabel } from './shown.ts';\n\nexport type LabelsState = { labels: Record<string, string> };\n\nexport const LabelsDoc = defineDoc<LabelsState>({\n kind: 'slicc.labels',\n version: 1,\n scope: 'session',\n initial: () => ({ labels: {} }),\n});\n\nexport const LABELS_KEPT = 500;\nexport const LABELS_PER_MINUTE = 6;\nconst MINUTE = 60_000;\nconst LABEL_WORDS = 8;\nconst LABEL_LENGTH = 80;\nconst OUTPUT_LENGTH = 600;\n\nexport const LABEL_WAIT_MS = 30_000;\n\nfunction callIdsOf(views: readonly ConversationView[]): Set<string> {\n const ids = new Set<string>();\n for (const view of views)\n for (const entry of view.entries) {\n const content = (entry.model?.[0] as Said | undefined)?.content;\n if (entry.kind === 'pi.assistant' && Array.isArray(content))\n for (const block of content as Block[])\n if (block.type === 'toolCall' && block.id) ids.add(block.id);\n }\n return ids;\n}\n\nexport function visibleLabels(\n labels: ReplicatedState<Record<string, string>>,\n sources: readonly ReplicatedState<unknown>[],\n views: () => readonly ConversationView[]\n) {\n const pick = () => {\n const ids = callIdsOf(views());\n return Object.fromEntries(\n Object.entries(labels.value as Record<string, string>).filter(([key]) =>\n key.split(' ').every((id) => ids.has(id))\n )\n );\n };\n const state = replicatedState<Record<string, string>>(pick());\n let queued = false;\n const update = () => {\n if (queued) return;\n queued = true;\n queueMicrotask(() => {\n queued = false;\n const next = pick();\n const before = state.value;\n const keys = Object.keys(next);\n if (\n keys.length !== Object.keys(before).length ||\n keys.some((key) => before[key] !== next[key])\n )\n state.replace(BACKGROUND_CONTEXT, next);\n });\n };\n const offs = [labels, ...sources].map((source) => source.subscribe(update));\n return {\n state,\n dispose() {\n for (const off of offs) off();\n },\n };\n}\n\nexport function watchLabel(\n labels: ReplicatedState<Record<string, string>>,\n waitMs = LABEL_WAIT_MS\n) {\n return (_agentId: string, callIds: readonly string[]): Promise<string | null> => {\n const found = shownLabel(labels.value, callIds);\n if (found !== undefined || !callIds.length) return Promise.resolve(found ?? null);\n return new Promise((resolve) => {\n const done = (label: string | null) => {\n clearTimeout(timer);\n off();\n resolve(label);\n };\n const timer = setTimeout(() => done(null), waitMs);\n const off = labels.subscribe(() => {\n const label = shownLabel(labels.value, callIds);\n if (label !== undefined) done(label);\n });\n });\n };\n}\n\nexport function cleanLabel(text: string): string {\n return text\n .replace(/\\s+/g, ' ')\n .trim()\n .replace(/^[\"'\u201C\u201D]+|[\"'\u201C\u201D]+$/g, '')\n .replace(/\\.+$/, '')\n .trim()\n .split(' ')\n .slice(0, LABEL_WORDS)\n .join(' ')\n .slice(0, LABEL_LENGTH);\n}\n\nexport type Run = { name: string; input: string; output: string; at: number };\n\ntype Block = { type?: string; id?: string; name?: string; arguments?: unknown };\n\ntype Said = { content?: unknown; toolCallId?: string; timestamp?: number };\n\nexport function clusterOf(\n entries: readonly EntryRecord[],\n callIds: readonly string[]\n): Run[] | undefined {\n const calls = new Map<string, Pick<Run, 'name' | 'input'>>();\n const results = new Map<string, Pick<Run, 'output' | 'at'>>();\n for (const entry of entries) {\n const said = entry.model?.[0] as Said | undefined;\n if (entry.kind === 'pi.assistant' && Array.isArray(said?.content))\n for (const block of said.content as Block[])\n if (block.type === 'toolCall' && block.id)\n calls.set(block.id, {\n name: block.name ?? 'tool',\n input: JSON.stringify(block.arguments ?? {}),\n });\n if (entry.kind === 'pi.tool-result' && said?.toolCallId)\n results.set(said.toolCallId, {\n output: answerText(said.content),\n at: said.timestamp ?? 0,\n });\n }\n const runs: Run[] = [];\n for (const id of callIds) {\n const call = calls.get(id);\n const result = results.get(id);\n if (!call || !result) return undefined;\n runs.push({ ...call, ...result });\n }\n return runs;\n}\n\nexport function describe(runs: readonly Run[]): string {\n return runs\n .map((run) => `${run.name}: ${run.input}\\n=> ${run.output.slice(0, OUTPUT_LENGTH)}`)\n .join('\\n\\n');\n}\n\ntype Counted = Record<'input' | 'output' | 'cacheRead' | 'cacheWrite' | 'totalTokens', number> & {\n cost: Record<'input' | 'output' | 'cacheRead' | 'cacheWrite' | 'total', number>;\n};\n\nasync function spend(tx: Tx, conversation: ConversationId, answer: AssistantMessage) {\n const models = (await tx.doc(UsageDoc, conversation)).models as unknown as Record<\n string,\n Counted\n >;\n const key = `${answer.provider}/${answer.model}`;\n const usage = answer.usage as Usage;\n const total = Object.hasOwn(models, key) ? models[key] : undefined;\n if (!total) {\n models[key] = JSON.parse(JSON.stringify(usage)) as Counted;\n return;\n }\n for (const field of ['input', 'output', 'cacheRead', 'cacheWrite', 'totalTokens'] as const)\n total[field] += usage[field];\n for (const field of ['input', 'output', 'cacheRead', 'cacheWrite', 'total'] as const)\n total.cost[field] += usage.cost[field];\n}\n\nexport interface LabelsAttach {\n harness: Pick<Harness, 'commit'>;\n agents: Pick<Agents, 'conversation'>;\n label: Labeler;\n vault?: Pick<ReplicatedState<VaultState>, 'value'>;\n now?: () => number;\n perMinute?: number;\n}\n\nexport interface LabelsRuntime {\n labels: ReplicatedState<Record<string, string>>;\n label(agentId: string, callIds: readonly string[], context: Context): Promise<string | null>;\n}\n\nfunction modelName(model: { provider: string; modelId: string } | undefined): string {\n return model ? `${model.provider}/${model.modelId}` : '';\n}\n\nexport async function attachLabels(\n options: LabelsAttach,\n context: Context = BACKGROUND_CONTEXT\n): Promise<LabelsRuntime> {\n const { harness, agents } = options;\n const now = options.now ?? Date.now;\n const started = now();\n const cap = options.perMinute ?? LABELS_PER_MINUTE;\n const loaded = await harness.commit(\n async (tx) => ({ ...(await tx.doc(LabelsDoc)).labels }),\n context\n );\n const labels = replicatedState<Record<string, string>>(loaded);\n const flying = new Map<string, Promise<string | null>>();\n const spent = new Map<string, number[]>();\n const admit = (agentId: string) => () => {\n const at = now();\n const recent = (spent.get(agentId) ?? []).filter((time) => at - time < MINUTE);\n spent.set(agentId, recent);\n if (recent.length >= cap) return false;\n recent.push(at);\n return true;\n };\n const keep = (\n key: string,\n label: string,\n conversation: ConversationId,\n answer: AssistantMessage\n ) =>\n harness.commit(async (tx) => {\n const doc = await tx.doc(LabelsDoc);\n doc.labels[key] = label;\n const keys = Object.keys(doc.labels);\n for (const old of keys.slice(0, Math.max(0, keys.length - LABELS_KEPT)))\n delete doc.labels[old];\n await spend(tx, conversation, answer);\n return { ...doc.labels };\n }, BACKGROUND_CONTEXT);\n const make = async (agentId: string, callIds: readonly string[], key: string) => {\n const conversation = await agents.conversation(agentId, BACKGROUND_CONTEXT);\n if (!conversation) return null;\n const runs = clusterOf((await conversation.context(BACKGROUND_CONTEXT)).entries, callIds);\n if (!runs || Math.max(...runs.map((run) => run.at)) < started) return null;\n if (vaultHold(options.vault?.value)) return null;\n const text = await scrubbed(describe(runs));\n const model = modelName((await conversation.agent(BACKGROUND_CONTEXT)).model);\n const asked = await options.label(text, model, BACKGROUND_CONTEXT, admit(agentId));\n if (!asked) return null;\n const label = cleanLabel(asked.text);\n labels.replace(BACKGROUND_CONTEXT, await keep(key, label, conversation.id, asked.answer));\n return label || null;\n };\n return {\n labels,\n label(agentId, callIds, _context) {\n if (!callIds.length) return Promise.resolve(null);\n const key = labelKey(callIds);\n const found = shownLabel(labels.value, callIds);\n if (found !== undefined) return Promise.resolve(found);\n const known = flying.get(key);\n if (known !== undefined) return known;\n const made = make(agentId, callIds, key)\n .catch(() => null)\n .finally(() => flying.delete(key));\n flying.set(key, made);\n return made;\n },\n };\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAA6C,uBAAuB;AACpE,SAAS,0BAA0B;AAEnC;AAAA,EAGE;AAAA,
|
|
4
|
+
"sourcesContent": ["import { type Context, type ReplicatedState, replicatedState } from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { AssistantMessage, Usage } from '@earendil-works/pi-ai';\nimport {\n type ConversationId,\n type ConversationView,\n defineDoc,\n type Harness,\n type Tx,\n UsageDoc,\n} from '@earendil-works/pi-durable';\nimport type { Agents } from '../agents.ts';\nimport type { VaultState } from '../secrets/vault.ts';\nimport { vaultHold } from '../secrets/view.ts';\nimport { callIdsOf, clusterOf, describe } from './cluster.ts';\nimport { type Labeler, scrubbed } from './generate.ts';\nimport { labelKey, shownLabel } from './shown.ts';\n\nexport type LabelsState = { labels: Record<string, string> };\n\nexport const LabelsDoc = defineDoc<LabelsState>({\n kind: 'slicc.labels',\n version: 1,\n scope: 'session',\n initial: () => ({ labels: {} }),\n});\n\nexport const LABELS_KEPT = 500;\nexport const LABELS_PER_MINUTE = 6;\nconst MINUTE = 60_000;\nconst LABEL_WORDS = 8;\nconst LABEL_LENGTH = 80;\nconst RESERVED = 2;\nconst POLL_MS = 1000;\nconst SETTLE_MS = 600_000;\n\nexport const LABEL_WAIT_MS = 30_000;\n\nexport function visibleLabels(\n labels: ReplicatedState<Record<string, string>>,\n sources: readonly ReplicatedState<unknown>[],\n views: () => readonly ConversationView[]\n) {\n const pick = () => {\n const ids = callIdsOf(views());\n return Object.fromEntries(\n Object.entries(labels.value as Record<string, string>).filter(([key]) =>\n key.split(' ').every((id) => ids.has(id))\n )\n );\n };\n const state = replicatedState<Record<string, string>>(pick());\n let queued = false;\n const update = () => {\n if (queued) return;\n queued = true;\n queueMicrotask(() => {\n queued = false;\n const next = pick();\n const before = state.value;\n const keys = Object.keys(next);\n if (\n keys.length !== Object.keys(before).length ||\n keys.some((key) => before[key] !== next[key])\n )\n state.replace(BACKGROUND_CONTEXT, next);\n });\n };\n const offs = [labels, ...sources].map((source) => source.subscribe(update));\n return {\n state,\n dispose() {\n for (const off of offs) off();\n },\n };\n}\n\nexport function watchLabel(\n labels: ReplicatedState<Record<string, string>>,\n waitMs = LABEL_WAIT_MS\n) {\n return (_agentId: string, callIds: readonly string[]): Promise<string | null> => {\n const found = shownLabel(labels.value, callIds);\n if (found !== undefined || !callIds.length) return Promise.resolve(found ?? null);\n return new Promise((resolve) => {\n const done = (label: string | null) => {\n clearTimeout(timer);\n off();\n resolve(label);\n };\n const timer = setTimeout(() => done(null), waitMs);\n const off = labels.subscribe(() => {\n const label = shownLabel(labels.value, callIds);\n if (label !== undefined) done(label);\n });\n });\n };\n}\n\nexport function cleanLabel(text: string): string {\n return text\n .replace(/\\s+/g, ' ')\n .trim()\n .replace(/^[\"'\u201C\u201D]+|[\"'\u201C\u201D]+$/g, '')\n .replace(/\\.+$/, '')\n .trim()\n .split(' ')\n .slice(0, LABEL_WORDS)\n .join(' ')\n .slice(0, LABEL_LENGTH);\n}\n\ntype Counted = Record<'input' | 'output' | 'cacheRead' | 'cacheWrite' | 'totalTokens', number> & {\n cost: Record<'input' | 'output' | 'cacheRead' | 'cacheWrite' | 'total', number>;\n};\n\nasync function spend(tx: Tx, conversation: ConversationId, answer: AssistantMessage) {\n const models = (await tx.doc(UsageDoc, conversation)).models as unknown as Record<\n string,\n Counted\n >;\n const key = `${answer.provider}/${answer.model}`;\n const usage = answer.usage as Usage;\n const total = Object.hasOwn(models, key) ? models[key] : undefined;\n if (!total) {\n models[key] = JSON.parse(JSON.stringify(usage)) as Counted;\n return;\n }\n for (const field of ['input', 'output', 'cacheRead', 'cacheWrite', 'totalTokens'] as const)\n total[field] += usage[field];\n for (const field of ['input', 'output', 'cacheRead', 'cacheWrite', 'total'] as const)\n total.cost[field] += usage.cost[field];\n}\n\nexport interface LabelsAttach {\n harness: Pick<Harness, 'commit'>;\n agents: Pick<Agents, 'conversation'>;\n label: Labeler;\n vault?: Pick<ReplicatedState<VaultState>, 'value'>;\n now?: () => number;\n perMinute?: number;\n pollMs?: number;\n settleMs?: number;\n}\n\nexport interface LabelsRuntime {\n labels: ReplicatedState<Record<string, string>>;\n label(agentId: string, callIds: readonly string[], context: Context): Promise<string | null>;\n}\n\nfunction modelName(model: { provider: string; modelId: string } | undefined): string {\n return model ? `${model.provider}/${model.modelId}` : '';\n}\n\nexport async function attachLabels(\n options: LabelsAttach,\n context: Context = BACKGROUND_CONTEXT\n): Promise<LabelsRuntime> {\n const { harness, agents } = options;\n const now = options.now ?? Date.now;\n const started = now();\n const cap = options.perMinute ?? LABELS_PER_MINUTE;\n const loaded = await harness.commit(\n async (tx) => ({ ...(await tx.doc(LabelsDoc)).labels }),\n context\n );\n const labels = replicatedState<Record<string, string>>(loaded);\n const flying = new Map<string, Promise<string | null>>();\n const waiting = new Set<string>();\n const spent = new Map<string, number[]>();\n const pollMs = options.pollMs ?? POLL_MS;\n const rounds = Math.ceil((options.settleMs ?? SETTLE_MS) / pollMs);\n const sleep = () => new Promise((resolve) => setTimeout(resolve, pollMs));\n const used = (agentId: string) => {\n const at = now();\n const recent = (spent.get(agentId) ?? []).filter((time) => at - time < MINUTE);\n spent.set(agentId, recent);\n return recent;\n };\n const admit = (agentId: string, settle: boolean) => () => {\n const recent = used(agentId);\n if (recent.length >= (settle ? cap : cap - RESERVED)) return false;\n recent.push(now());\n return true;\n };\n const room = async (agentId: string) => {\n for (let round = 0; round < rounds && used(agentId).length >= cap; round++) await sleep();\n };\n const keep = (\n key: string,\n label: string,\n conversation: ConversationId,\n answer: AssistantMessage\n ) =>\n harness.commit(async (tx) => {\n const doc = await tx.doc(LabelsDoc);\n doc.labels[key] = label;\n const keys = Object.keys(doc.labels);\n for (const old of keys.slice(0, Math.max(0, keys.length - LABELS_KEPT)))\n delete doc.labels[old];\n await spend(tx, conversation, answer);\n return { ...doc.labels };\n }, BACKGROUND_CONTEXT);\n const read = async (agentId: string, callIds: readonly string[]) => {\n const conversation = await agents.conversation(agentId, BACKGROUND_CONTEXT);\n if (!conversation) return undefined;\n const cluster = clusterOf((await conversation.context(BACKGROUND_CONTEXT)).entries, callIds);\n return cluster ? { conversation, cluster } : undefined;\n };\n type Read = NonNullable<Awaited<ReturnType<typeof read>>>;\n const ask = async (agentId: string, key: string, found: Read, settle: boolean) => {\n if (vaultHold(options.vault?.value)) return null;\n if (settle) await room(agentId);\n const text = await scrubbed(describe(found.cluster.runs));\n const model = modelName((await found.conversation.agent(BACKGROUND_CONTEXT)).model);\n const asked = await options.label(text, model, BACKGROUND_CONTEXT, admit(agentId, settle));\n if (!asked) return null;\n const label = cleanLabel(asked.text);\n labels.replace(BACKGROUND_CONTEXT, await keep(key, label, found.conversation.id, asked.answer));\n return label || null;\n };\n const longer = (key: string) =>\n [...flying.keys(), ...waiting, ...Object.keys(labels.value)].some((other) =>\n other.startsWith(`${key} `)\n );\n const prefixOf = (callIds: readonly string[]) => {\n for (let size = callIds.length - 1; size > 0; size--) {\n const part = callIds.slice(0, size);\n const key = labelKey(part);\n const shown = flying.get(key) ?? shownLabel(labels.value, part);\n if (shown !== undefined) return Promise.resolve(shown);\n if (waiting.has(key)) return Promise.resolve(null);\n }\n return undefined;\n };\n const settled = async (agentId: string, callIds: readonly string[], key: string) => {\n for (let round = 0; round < rounds; round++) {\n await sleep();\n if (longer(key)) return undefined;\n const found = await read(agentId, callIds);\n if (found?.cluster.settled) return found;\n }\n return undefined;\n };\n const relabel = async (agentId: string, callIds: readonly string[], key: string) => {\n const found = await settled(agentId, callIds, key);\n return found ? ask(agentId, key, found, true) : undefined;\n };\n const make = async (agentId: string, callIds: readonly string[], key: string) => {\n const found = await read(agentId, callIds);\n if (!found || found.cluster.at < started) return null;\n const prefix = prefixOf(callIds);\n if (longer(key)) return (await prefix) ?? null;\n if (found.cluster.settled) return ask(agentId, key, found, prefix !== undefined);\n if (prefix !== undefined) {\n const shown = await prefix;\n return (await relabel(agentId, callIds, key)) ?? shown;\n }\n const first = await ask(agentId, key, found, false);\n waiting.add(key);\n void relabel(agentId, callIds, key)\n .catch(() => undefined)\n .finally(() => waiting.delete(key));\n return first;\n };\n return {\n labels,\n label(agentId, callIds, _context) {\n if (!callIds.length) return Promise.resolve(null);\n const key = labelKey(callIds);\n const found = shownLabel(labels.value, callIds);\n if (found !== undefined) return Promise.resolve(found);\n const known = flying.get(key);\n if (known !== undefined) return known;\n const made = make(agentId, callIds, key)\n .catch(() => null)\n .finally(() => flying.delete(key));\n flying.set(key, made);\n return made;\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/types/client.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ export interface AgentConnection {
|
|
|
30
30
|
readonly remote?: AgentRemote;
|
|
31
31
|
readonly pages?: AgentPages;
|
|
32
32
|
readonly closed: Promise<Error | undefined>;
|
|
33
|
+
readonly mismatch?: string;
|
|
33
34
|
prompt(text: string, whenBusy?: SendMode): Promise<string>;
|
|
34
35
|
webhook(name: string, delivery: {
|
|
35
36
|
id?: string | null;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { AgentConnection } from './client.ts';
|
|
2
|
+
export declare const NEWER_AGENT = "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.";
|
|
3
|
+
export declare function mismatched(serverId: string): AgentConnection;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type Context, type ReplicatedState } from '@earendil-works/chord';
|
|
2
|
+
import { type Harness } from '@earendil-works/pi-durable';
|
|
3
|
+
import type { VaultRecords } from './records.ts';
|
|
4
|
+
import type { Vault } from './vault.ts';
|
|
5
|
+
export declare const LEGACY_DATABASE = "slicc-agent-credentials";
|
|
6
|
+
export type MovedAccount = {
|
|
7
|
+
kind: 'model';
|
|
8
|
+
provider: string;
|
|
9
|
+
label: string;
|
|
10
|
+
} | {
|
|
11
|
+
kind: 'mcp';
|
|
12
|
+
server: string;
|
|
13
|
+
label: string;
|
|
14
|
+
};
|
|
15
|
+
export type MovedState = {
|
|
16
|
+
accounts: MovedAccount[];
|
|
17
|
+
dismissed: boolean;
|
|
18
|
+
};
|
|
19
|
+
export declare const MovedDoc: import("@earendil-works/pi-durable").SessionDocToken<MovedState>;
|
|
20
|
+
export declare function movedAccount(key: string): MovedAccount;
|
|
21
|
+
export declare const WIPE_WAIT_MS = 3000;
|
|
22
|
+
export interface Wiped {
|
|
23
|
+
now: MovedAccount[];
|
|
24
|
+
later: Promise<MovedAccount[]>;
|
|
25
|
+
}
|
|
26
|
+
export declare function wipeLegacy(factory?: IDBFactory | undefined, wait?: number): Promise<Wiped>;
|
|
27
|
+
export interface KeysMoved {
|
|
28
|
+
readonly state: ReplicatedState<string[]>;
|
|
29
|
+
dismiss(context: Context): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
type Records = Pick<VaultRecords, 'state' | 'model' | 'mcp' | 'refresh'>;
|
|
32
|
+
export declare function keysMoved(harness: Pick<Harness, 'commit'>, sources: {
|
|
33
|
+
records: Records;
|
|
34
|
+
vault: Pick<Vault, 'connected'>;
|
|
35
|
+
}, wiped: Wiped, context?: Context): Promise<KeysMoved>;
|
|
36
|
+
export {};
|
package/dist/types/services.d.ts
CHANGED
|
@@ -312,11 +312,13 @@ export interface SettingsState {
|
|
|
312
312
|
models: ModelChoice[];
|
|
313
313
|
accounts: AccountState[];
|
|
314
314
|
budget?: BudgetState | null;
|
|
315
|
+
moved?: string[];
|
|
315
316
|
}
|
|
316
317
|
export interface AgentSettings {
|
|
317
318
|
readonly state: ReplicatedState<SettingsState>;
|
|
318
319
|
connect(providerId: string, secret: string | null, fields: Record<string, string> | null, context: Context): Promise<void>;
|
|
319
320
|
disconnect(providerId: string, context: Context): Promise<void>;
|
|
320
321
|
signIn(providerId: string, context: Context): Promise<SignIn | McpSignIn | null>;
|
|
322
|
+
dismissMoved(context: Context): Promise<void>;
|
|
321
323
|
}
|
|
322
324
|
export declare const AgentSettings: import("@earendil-works/chord").Service<AgentSettings>;
|
package/dist/types/settings.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { CredentialStore, Provider } from '@earendil-works/pi-ai';
|
|
|
2
2
|
import { type MutableModels } from '@earendil-works/pi-ai/models';
|
|
3
3
|
import { type Budget } from './adobe.ts';
|
|
4
4
|
import type { McpAccounts } from './mcp/index.ts';
|
|
5
|
+
import type { KeysMoved } from './secrets/legacy.ts';
|
|
5
6
|
import type { VaultRecords } from './secrets/records.ts';
|
|
6
7
|
import type { PlainStore } from './secrets/store.ts';
|
|
7
8
|
import type { AccountField, AgentSettings } from './services.ts';
|
|
@@ -37,4 +38,5 @@ export declare function createAgentSettings(models: MutableModels, sources: Sett
|
|
|
37
38
|
usage?: UsageReader;
|
|
38
39
|
every?: number;
|
|
39
40
|
mcp?: McpAccounts;
|
|
41
|
+
moved?: KeysMoved;
|
|
40
42
|
}): Promise<AgentSettings>;
|
|
@@ -4,6 +4,7 @@ import { AgentAdapter } from './agent-port.ts';
|
|
|
4
4
|
import { ChangesAdapter } from './changes-port.ts';
|
|
5
5
|
import { MemoryAdapter } from './memory-port.ts';
|
|
6
6
|
import { MonitorAdapter } from './monitor-port.ts';
|
|
7
|
+
import { NoticesAdapter } from './notices-port.ts';
|
|
7
8
|
import { PageAdapter, type PageOptions } from './page-port.ts';
|
|
8
9
|
import { type Login, SettingsAdapter } from './settings-port.ts';
|
|
9
10
|
import { SprinkleAdapter } from './sprinkle-port.ts';
|
|
@@ -13,6 +14,7 @@ export { ChangesAdapter, type ChangesEvents } from './changes-port.ts';
|
|
|
13
14
|
export { MemoryAdapter } from './memory-port.ts';
|
|
14
15
|
export { assistant, errorAction, errorPart, isBusy, queued, textOf, toMessages, } from './messages.ts';
|
|
15
16
|
export { MonitorAdapter, type MonitorAdapterOptions, type MonitorInput, monitorSnapshot, } from './monitor-port.ts';
|
|
17
|
+
export { KEYS_MOVED, movedNotice, NoticesAdapter } from './notices-port.ts';
|
|
16
18
|
export { PageAdapter, type PageDocument, type PageOptions, type PageRun, type PageTarget, } from './page-port.ts';
|
|
17
19
|
export { type Login, SETTINGS_KEY, SettingsAdapter } from './settings-port.ts';
|
|
18
20
|
export { SprinkleAdapter } from './sprinkle-port.ts';
|
|
@@ -32,5 +34,6 @@ export declare function createAgentModel(connection: AgentConnection, options?:
|
|
|
32
34
|
memory: MemoryAdapter;
|
|
33
35
|
changes: ChangesAdapter;
|
|
34
36
|
monitor: MonitorAdapter;
|
|
37
|
+
notices: NoticesAdapter;
|
|
35
38
|
page: PageAdapter | null;
|
|
36
39
|
};
|
|
@@ -36,6 +36,8 @@ interface ModelMessage {
|
|
|
36
36
|
}
|
|
37
37
|
export declare function textOf(content: ModelMessage['content']): string;
|
|
38
38
|
export declare function fromPatch(patch: string): ToolCall['diff'];
|
|
39
|
+
export declare const CONNECT_IT = "Connect it in Settings \u203A Accounts.";
|
|
40
|
+
export declare function providerName(provider: string | undefined, fallback?: string): string;
|
|
39
41
|
export declare function errorPart(error: string, provider?: string): MessagePart;
|
|
40
42
|
export declare function errorAction(message: string): ErrorAction;
|
|
41
43
|
export declare function assistant(id: string, message: ModelMessage, status?: AssistantStatus): AssistantMessage;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Notice, NoticesPort } from '@ai-ecoverse/slicc-spectrum/ui';
|
|
2
|
+
import type { AgentSettings } from '../services.ts';
|
|
3
|
+
import { type Report } from './attempt.ts';
|
|
4
|
+
import { Emitter } from './emitter.ts';
|
|
5
|
+
export declare const KEYS_MOVED = "keys-moved";
|
|
6
|
+
export declare function movedNotice(accounts: readonly string[]): Notice;
|
|
7
|
+
export declare class NoticesAdapter extends Emitter<{
|
|
8
|
+
notices: readonly Notice[];
|
|
9
|
+
}> implements NoticesPort {
|
|
10
|
+
#private;
|
|
11
|
+
constructor(settings: AgentSettings, report: Report);
|
|
12
|
+
list(): readonly Notice[];
|
|
13
|
+
act(): Promise<void>;
|
|
14
|
+
dismiss(id: string): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ConversationView, EntryRecord } from '@earendil-works/pi-durable';
|
|
2
|
+
export type Run = {
|
|
3
|
+
name: string;
|
|
4
|
+
input: string;
|
|
5
|
+
output: string;
|
|
6
|
+
done: boolean;
|
|
7
|
+
};
|
|
8
|
+
export type Cluster = {
|
|
9
|
+
runs: Run[];
|
|
10
|
+
at: number;
|
|
11
|
+
settled: boolean;
|
|
12
|
+
};
|
|
13
|
+
export declare function callIdsOf(views: readonly ConversationView[]): Set<string>;
|
|
14
|
+
export declare function clusterOf(entries: readonly EntryRecord[], callIds: readonly string[]): Cluster | undefined;
|
|
15
|
+
export declare function describe(runs: readonly Run[]): string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Context, type ReplicatedState } from '@earendil-works/chord';
|
|
2
|
-
import { type ConversationView, type
|
|
2
|
+
import { type ConversationView, type Harness } from '@earendil-works/pi-durable';
|
|
3
3
|
import type { Agents } from '../agents.ts';
|
|
4
4
|
import type { VaultState } from '../secrets/vault.ts';
|
|
5
5
|
import { type Labeler } from './generate.ts';
|
|
@@ -16,14 +16,6 @@ export declare function visibleLabels(labels: ReplicatedState<Record<string, str
|
|
|
16
16
|
};
|
|
17
17
|
export declare function watchLabel(labels: ReplicatedState<Record<string, string>>, waitMs?: number): (_agentId: string, callIds: readonly string[]) => Promise<string | null>;
|
|
18
18
|
export declare function cleanLabel(text: string): string;
|
|
19
|
-
export type Run = {
|
|
20
|
-
name: string;
|
|
21
|
-
input: string;
|
|
22
|
-
output: string;
|
|
23
|
-
at: number;
|
|
24
|
-
};
|
|
25
|
-
export declare function clusterOf(entries: readonly EntryRecord[], callIds: readonly string[]): Run[] | undefined;
|
|
26
|
-
export declare function describe(runs: readonly Run[]): string;
|
|
27
19
|
export interface LabelsAttach {
|
|
28
20
|
harness: Pick<Harness, 'commit'>;
|
|
29
21
|
agents: Pick<Agents, 'conversation'>;
|
|
@@ -31,6 +23,8 @@ export interface LabelsAttach {
|
|
|
31
23
|
vault?: Pick<ReplicatedState<VaultState>, 'value'>;
|
|
32
24
|
now?: () => number;
|
|
33
25
|
perMinute?: number;
|
|
26
|
+
pollMs?: number;
|
|
27
|
+
settleMs?: number;
|
|
34
28
|
}
|
|
35
29
|
export interface LabelsRuntime {
|
|
36
30
|
labels: ReplicatedState<Record<string, string>>;
|
package/dist/types/wire.d.ts
CHANGED
|
@@ -11,6 +11,12 @@ export type Frame = {
|
|
|
11
11
|
} | {
|
|
12
12
|
close: true;
|
|
13
13
|
} | Uint8Array;
|
|
14
|
+
export declare const LINK_PROTOCOL = 1;
|
|
15
|
+
export interface Greeting {
|
|
16
|
+
protocol: number;
|
|
17
|
+
serverId: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function greeted(hello: string): Greeting;
|
|
14
20
|
export declare function post(endpoint: PortEndpoint, chunk: Uint8Array): void;
|
|
15
21
|
export declare function withUnrefTimers<T>(run: () => T, scope?: {
|
|
16
22
|
setTimeout: typeof setTimeout;
|
package/dist/wire.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
const LINK_PROTOCOL = 1;
|
|
2
|
+
const GREETING = /^slicc-agent-link\/(\d+) (.+)$/;
|
|
3
|
+
function greeted(hello) {
|
|
4
|
+
const found = GREETING.exec(hello);
|
|
5
|
+
return found ? { protocol: Number(found[1]), serverId: found[2] } : { protocol: LINK_PROTOCOL, serverId: hello };
|
|
6
|
+
}
|
|
1
7
|
function post(endpoint, chunk) {
|
|
2
8
|
const copy = chunk.slice();
|
|
3
9
|
endpoint.postMessage(copy, [copy.buffer]);
|
|
@@ -98,7 +104,9 @@ class PortChannel {
|
|
|
98
104
|
}
|
|
99
105
|
}
|
|
100
106
|
export {
|
|
107
|
+
LINK_PROTOCOL,
|
|
101
108
|
PortChannel,
|
|
109
|
+
greeted,
|
|
102
110
|
post,
|
|
103
111
|
withUnrefTimers
|
|
104
112
|
};
|
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 { ByteTransportFactory, ByteTransportHandlers } from '@earendil-works/pi-client';\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\nexport function post(endpoint: PortEndpoint, chunk: Uint8Array): void {\n const copy = chunk.slice();\n endpoint.postMessage(copy, [copy.buffer]);\n}\n\nfunction unrefable(id: number): object {\n return {\n unref() {\n return this;\n },\n ref() {\n return this;\n },\n [Symbol.toPrimitive]: () => id,\n };\n}\n\nexport function withUnrefTimers<T>(\n run: () => T,\n scope: { setTimeout: typeof setTimeout } = globalThis\n): T {\n const original = scope.setTimeout;\n scope.setTimeout = ((...args: Parameters<typeof setTimeout>) => {\n const id: unknown = original(...args);\n return typeof id === 'number' ? unrefable(id) : id;\n }) as typeof setTimeout;\n try {\n return run();\n } finally {\n scope.setTimeout = original;\n }\n}\n\nexport class PortChannel {\n readonly hello: Promise<string>;\n readonly ended: Promise<Error | undefined>;\n readonly #endpoint: PortEndpoint;\n readonly #queue: Uint8Array[] = [];\n #handlers: ByteTransportHandlers | undefined;\n #ended: 'close' | Error | undefined;\n #greet!: (serverId: 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.ended = new Promise((finish) => {\n this.#finish = finish;\n });\n endpoint.addEventListener('message', ({ data }) => this.#receive(data as Frame));\n endpoint.addEventListener('messageerror', (event) =>\n this.#end(new Error(`agent port ${event.type}`))\n );\n endpoint.addEventListener('error', (event) => this.#end(new Error(`agent port ${event.type}`)));\n endpoint.addEventListener('close', () => this.#end('close'));\n endpoint.start?.();\n }\n\n readonly transport: ByteTransportFactory = (handlers) => {\n this.#handlers = handlers;\n for (const chunk of this.#queue.splice(0)) handlers.onData(chunk);\n if (this.#ended) this.#deliver(this.#ended);\n return {\n send: async (chunk) => {\n if (this.#ended) throw new Error('agent port is closed');\n post(this.#endpoint, chunk);\n },\n close: () => {\n if (this.#ended) return;\n this.#ended = 'close';\n this.#refuse(new Error('agent port closed before hello'));\n this.#finish(undefined);\n this.#endpoint.postMessage({ close: true } satisfies Frame);\n this.#endpoint.close?.();\n },\n };\n };\n\n #receive(frame: Frame): void {\n if (frame instanceof Uint8Array) {\n if (this.#handlers) this.#handlers.onData(frame);\n else this.#queue.push(frame);\n } else if ('hello' in frame) {\n this.#greet(frame.hello);\n } else {\n this.#end('close');\n }\n }\n\n #end(reason: 'close' | Error): void {\n if (this.#ended) return;\n this.#ended = reason;\n this.#refuse(reason === 'close' ? new Error('agent port closed before hello') : reason);\n this.#finish(reason === 'close' ? undefined : reason);\n this.#deliver(reason);\n }\n\n #deliver(reason: 'close' | Error): void {\n const handlers = this.#handlers;\n if (!handlers) return;\n this.#handlers = undefined;\n if (reason === 'close') handlers.onClose();\n else handlers.onError(reason);\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type { ByteTransportFactory, ByteTransportHandlers } from '@earendil-works/pi-client';\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\nexport const LINK_PROTOCOL = 1;\n\nconst GREETING = /^slicc-agent-link\\/(\\d+) (.+)$/;\n\nexport interface Greeting {\n protocol: number;\n serverId: string;\n}\n\nexport function greeted(hello: string): Greeting {\n const found = GREETING.exec(hello);\n return found\n ? { protocol: Number(found[1]), serverId: found[2] as string }\n : { protocol: LINK_PROTOCOL, serverId: hello };\n}\n\nexport function post(endpoint: PortEndpoint, chunk: Uint8Array): void {\n const copy = chunk.slice();\n endpoint.postMessage(copy, [copy.buffer]);\n}\n\nfunction unrefable(id: number): object {\n return {\n unref() {\n return this;\n },\n ref() {\n return this;\n },\n [Symbol.toPrimitive]: () => id,\n };\n}\n\nexport function withUnrefTimers<T>(\n run: () => T,\n scope: { setTimeout: typeof setTimeout } = globalThis\n): T {\n const original = scope.setTimeout;\n scope.setTimeout = ((...args: Parameters<typeof setTimeout>) => {\n const id: unknown = original(...args);\n return typeof id === 'number' ? unrefable(id) : id;\n }) as typeof setTimeout;\n try {\n return run();\n } finally {\n scope.setTimeout = original;\n }\n}\n\nexport class PortChannel {\n readonly hello: Promise<string>;\n readonly ended: Promise<Error | undefined>;\n readonly #endpoint: PortEndpoint;\n readonly #queue: Uint8Array[] = [];\n #handlers: ByteTransportHandlers | undefined;\n #ended: 'close' | Error | undefined;\n #greet!: (serverId: 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.ended = new Promise((finish) => {\n this.#finish = finish;\n });\n endpoint.addEventListener('message', ({ data }) => this.#receive(data as Frame));\n endpoint.addEventListener('messageerror', (event) =>\n this.#end(new Error(`agent port ${event.type}`))\n );\n endpoint.addEventListener('error', (event) => this.#end(new Error(`agent port ${event.type}`)));\n endpoint.addEventListener('close', () => this.#end('close'));\n endpoint.start?.();\n }\n\n readonly transport: ByteTransportFactory = (handlers) => {\n this.#handlers = handlers;\n for (const chunk of this.#queue.splice(0)) handlers.onData(chunk);\n if (this.#ended) this.#deliver(this.#ended);\n return {\n send: async (chunk) => {\n if (this.#ended) throw new Error('agent port is closed');\n post(this.#endpoint, chunk);\n },\n close: () => {\n if (this.#ended) return;\n this.#ended = 'close';\n this.#refuse(new Error('agent port closed before hello'));\n this.#finish(undefined);\n this.#endpoint.postMessage({ close: true } satisfies Frame);\n this.#endpoint.close?.();\n },\n };\n };\n\n #receive(frame: Frame): void {\n if (frame instanceof Uint8Array) {\n if (this.#handlers) this.#handlers.onData(frame);\n else this.#queue.push(frame);\n } else if ('hello' in frame) {\n this.#greet(frame.hello);\n } else {\n this.#end('close');\n }\n }\n\n #end(reason: 'close' | Error): void {\n if (this.#ended) return;\n this.#ended = reason;\n this.#refuse(reason === 'close' ? new Error('agent port closed before hello') : reason);\n this.#finish(reason === 'close' ? undefined : reason);\n this.#deliver(reason);\n }\n\n #deliver(reason: 'close' | Error): void {\n const handlers = this.#handlers;\n if (!handlers) return;\n this.#handlers = undefined;\n if (reason === 'close') handlers.onClose();\n else handlers.onError(reason);\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": "4.3.
|
|
3
|
+
"version": "4.3.2",
|
|
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",
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@ai-ecoverse/slicc-kernel": "1.47.1",
|
|
65
65
|
"@ai-ecoverse/slicc-scrub": "1.0.0",
|
|
66
|
-
"@ai-ecoverse/slicc-shared-web": "1.
|
|
67
|
-
"@ai-ecoverse/slicc-spectrum": "1.
|
|
66
|
+
"@ai-ecoverse/slicc-shared-web": "1.14.0",
|
|
67
|
+
"@ai-ecoverse/slicc-spectrum": "1.72.0",
|
|
68
68
|
"@ai-ecoverse/wasm-bash": "5.3.0-18",
|
|
69
69
|
"@ai-ecoverse/wasm-coreutils": "9.12.0-5",
|
|
70
70
|
"@ai-ecoverse/wasm-git": "2.55.0-15",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"fake-indexeddb": "6.2.5",
|
|
75
75
|
"lefthook": "2.1.17",
|
|
76
76
|
"monocart-coverage-reports": "2.13.2",
|
|
77
|
-
"playwright-core": "1.
|
|
77
|
+
"playwright-core": "1.64.0",
|
|
78
78
|
"semantic-release": "25.0.9",
|
|
79
79
|
"typescript": "7.0.2"
|
|
80
80
|
},
|