@ai-ecoverse/slicc-agent 3.6.0 → 3.7.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 +20 -3
- package/bin/agent +76 -0
- package/dist/agent.js +7 -14
- package/dist/agent.js.map +2 -2
- package/dist/agents.js +133 -0
- package/dist/agents.js.map +7 -0
- package/dist/client.js +3 -1
- package/dist/client.js.map +2 -2
- package/dist/cone.js +2 -16
- package/dist/cone.js.map +2 -2
- package/dist/control.js +68 -10
- package/dist/control.js.map +2 -2
- package/dist/host.js +11 -2
- package/dist/host.js.map +2 -2
- package/dist/kernel/env.js +30 -3
- package/dist/kernel/env.js.map +2 -2
- package/dist/kernel/exec.js +2 -1
- package/dist/kernel/exec.js.map +2 -2
- package/dist/kernel/groups.js +31 -0
- package/dist/kernel/groups.js.map +7 -0
- package/dist/licks/index.js +16 -1
- package/dist/licks/index.js.map +2 -2
- package/dist/licks/lick.js.map +1 -1
- package/dist/licks/licks.js +12 -1
- package/dist/licks/licks.js.map +2 -2
- package/dist/main.js +38 -9
- package/dist/main.js.map +2 -2
- package/dist/roles/frontmatter.js +59 -0
- package/dist/roles/frontmatter.js.map +7 -0
- package/dist/roles/roles.js +204 -0
- package/dist/roles/roles.js.map +7 -0
- package/dist/scoops/cli.js +391 -0
- package/dist/scoops/cli.js.map +7 -0
- package/dist/scoops/extension.js +301 -0
- package/dist/scoops/extension.js.map +7 -0
- package/dist/scoops/identity.js +33 -0
- package/dist/scoops/identity.js.map +7 -0
- package/dist/scoops/index.js +120 -0
- package/dist/scoops/index.js.map +7 -0
- package/dist/scoops/requests.js +136 -0
- package/dist/scoops/requests.js.map +7 -0
- package/dist/scoops/service.js +409 -0
- package/dist/scoops/service.js.map +7 -0
- package/dist/scoops/sync.js +252 -0
- package/dist/scoops/sync.js.map +7 -0
- package/dist/scoops/visible.js +15 -0
- package/dist/scoops/visible.js.map +7 -0
- package/dist/services.js.map +2 -2
- package/dist/spectrum/agent-port.js +137 -54
- package/dist/spectrum/agent-port.js.map +2 -2
- package/dist/spectrum/messages.js +19 -10
- package/dist/spectrum/messages.js.map +2 -2
- package/dist/types/agent.d.ts +3 -1
- package/dist/types/agents.d.ts +54 -0
- package/dist/types/client.d.ts +3 -1
- package/dist/types/cone.d.ts +1 -3
- package/dist/types/control.d.ts +7 -1
- package/dist/types/host.d.ts +2 -1
- package/dist/types/kernel/client.d.ts +4 -0
- package/dist/types/kernel/env.d.ts +13 -2
- package/dist/types/kernel/exec.d.ts +2 -2
- package/dist/types/kernel/groups.d.ts +7 -0
- package/dist/types/licks/index.d.ts +5 -0
- package/dist/types/licks/lick.d.ts +1 -1
- package/dist/types/licks/licks.d.ts +2 -1
- package/dist/types/main.d.ts +3 -0
- package/dist/types/roles/frontmatter.d.ts +7 -0
- package/dist/types/roles/roles.d.ts +48 -0
- package/dist/types/scoops/cli.d.ts +66 -0
- package/dist/types/scoops/extension.d.ts +63 -0
- package/dist/types/scoops/identity.d.ts +6 -0
- package/dist/types/scoops/index.d.ts +37 -0
- package/dist/types/scoops/requests.d.ts +32 -0
- package/dist/types/scoops/service.d.ts +116 -0
- package/dist/types/scoops/sync.d.ts +22 -0
- package/dist/types/scoops/visible.d.ts +4 -0
- package/dist/types/services.d.ts +30 -0
- package/dist/types/spectrum/agent-port.d.ts +13 -11
- package/dist/types/views.d.ts +12 -0
- package/dist/views.js +89 -0
- package/dist/views.js.map +7 -0
- package/package.json +5 -3
- package/packages/vfs-root/agents/delegate.md +8 -0
- package/packages/vfs-root/agents/oracle.md +25 -0
- package/packages/vfs-root/agents/reviewer.md +23 -0
- package/packages/vfs-root/agents/scout.md +30 -0
- package/packages/vfs-root/agents/worker.md +23 -0
- package/packages/vfs-root/skills/agent/SKILL.md +72 -0
package/dist/licks/licks.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/licks/licks.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport {\n type Conversation,\n defineDoc,\n type Harness,\n type SubmissionId,\n} from '@earendil-works/pi-durable';\nimport {\n formatLick,\n type Lick,\n type LickAction,\n type LickChannel,\n type LickSeverity,\n type LickTarget,\n lickId,\n} from './lick.ts';\nimport { entryLick, LICK_STATE_KIND, type LickDecision, lickDecisions } from './state.ts';\n\nexport interface LickEvent {\n channel: LickChannel;\n source: string;\n title: string;\n text: string;\n body?: string;\n items?: string[];\n count?: number;\n target: LickTarget;\n coalesce?: boolean;\n severity?: LickSeverity;\n eventId?: string;\n at?: number;\n}\n\ntype Pending = {\n lick: Lick;\n items: string[];\n body: string | null;\n};\n\ntype Queue = {\n submission: number | null;\n pending: Pending | null;\n};\n\ntype OutboxState = {\n queues: Record<string, Queue>;\n events: Record<string, string[]>;\n};\n\nexport const LicksOutbox = defineDoc<OutboxState>({\n kind: 'slicc.licks',\n version: 1,\n scope: 'session',\n initial: () => ({ queues: {}, events: {} }),\n});\n\nexport interface LickHandler {\n confirm?(lick: Lick, reason: string | undefined, context: Context): Promise<string | undefined>;\n dismiss?(lick: Lick, reason: string | undefined, context: Context): Promise<string | undefined>;\n}\n\nexport interface LickFound {\n lick: Lick;\n decision: LickDecision | undefined;\n}\n\nexport interface Licks {\n deliver(event: LickEvent, context: Context): Promise<void>;\n flush(context: Context): Promise<void>;\n find(conversation: Conversation, id: string, context: Context): Promise<LickFound | undefined>;\n decide(\n conversation: Conversation,\n id: string,\n action: LickAction,\n reason: string | undefined,\n context: Context\n ): Promise<string>;\n handle(channel: LickChannel, handler: LickHandler): void;\n pending(context: Context): Promise<number>;\n}\n\nexport interface LicksHost {\n harness: Harness;\n resolve(target: LickTarget, context: Context): Promise<Conversation>;\n}\n\nexport const MAX_ITEMS = 50;\nexport const MAX_EVENTS = 64;\n\nexport function render(pending: Pending): Lick {\n const shown = pending.items.slice(0, MAX_ITEMS);\n const more = pending.items.length - shown.length;\n const lines = [\n ...(pending.body ? [pending.body] : []),\n ...shown,\n ...(more > 0 ? [`\u2026 and ${more} more`] : []),\n ];\n const { body: _, ...lick } = pending.lick;\n return lines.length ? { ...lick, body: lines.join('\\n') } : lick;\n}\n\nconst RANK: Record<LickSeverity, number> = { warn: 1, error: 2 };\n\nexport function strongest(\n a: LickSeverity | undefined,\n b: LickSeverity | undefined\n): LickSeverity | undefined {\n if (!a) return b;\n if (!b) return a;\n return RANK[b] > RANK[a] ? b : a;\n}\n\nfunction merge(pending: Pending, event: LickEvent, now: number): Pending {\n const items = [...pending.items];\n for (const item of event.items ?? []) if (!items.includes(item)) items.push(item);\n const { severity: _, ...lick } = pending.lick;\n const severity = strongest(pending.lick.severity, event.severity);\n return {\n lick: {\n ...lick,\n title: event.title,\n text: event.text,\n count: pending.lick.count + (event.count ?? 1),\n at: event.at ?? now,\n ...(severity ? { severity } : {}),\n },\n items,\n body: event.body ?? pending.body,\n };\n}\n\nfunction fresh(event: LickEvent, now: number, listed: LickAction[] | undefined): Pending {\n return {\n lick: {\n id: lickId(),\n channel: event.channel,\n source: event.source,\n title: event.title,\n text: event.text,\n count: event.count ?? 1,\n at: now,\n ...(listed ? { actions: listed } : {}),\n ...(event.severity ? { severity: event.severity } : {}),\n },\n items: [...new Set(event.items ?? [])],\n body: event.body ?? null,\n };\n}\n\nfunction keyOf(event: LickEvent): string {\n const base = `${event.target}|${event.channel}|${event.source}`;\n return event.coalesce === false ? `${base}|${event.eventId ?? lickId()}` : base;\n}\n\nexport function createLicks(host: Promise<LicksHost>): Licks {\n const handlers = new Map<LickChannel, LickHandler>();\n let lock: Promise<unknown> = Promise.resolve();\n const serial = <T>(operation: () => Promise<T>): Promise<T> => {\n const run = lock.then(operation, operation);\n lock = run.catch(() => undefined);\n return run;\n };\n\n const actions = (channel: LickChannel): LickAction[] | undefined => {\n const handler = handlers.get(channel);\n const list: LickAction[] = [];\n if (handler?.confirm) list.push('confirm');\n if (handler?.dismiss) list.push('dismiss');\n return list.length ? list : undefined;\n };\n\n async function previous(\n harness: Harness,\n id: number | null,\n context: Context\n ): Promise<'queued' | 'withdrawn' | 'gone'> {\n if (id === null) return 'gone';\n const submission = await harness.submission(id as SubmissionId, context);\n const record = await submission?.status(context);\n if (record?.status === 'queued') return 'queued';\n return record?.status === 'unanswered' && record.reason === 'aborted' ? 'withdrawn' : 'gone';\n }\n\n async function settled(key: string, context: Context): Promise<Queue | undefined> {\n const { harness } = await host;\n const queue = (await harness.snapshot(LicksOutbox, context))?.queues[key];\n if (!queue) return undefined;\n const before = await previous(harness, queue.submission, context);\n if (before === 'queued') return undefined;\n if (queue.pending && before === 'gone') return queue;\n await harness.commit(async (tx) => {\n const doc = await tx.doc(LicksOutbox);\n if (doc.queues[key]?.submission === queue.submission) delete doc.queues[key];\n }, context);\n return undefined;\n }\n\n async function flushKey(key: string, context: Context): Promise<void> {\n const { harness, resolve } = await host;\n const queue = await settled(key, context);\n if (!queue?.pending) return;\n const lick = render(queue.pending);\n const target = key.split('|')[0] as LickTarget;\n const conversation = await resolve(target, context);\n const submission = await conversation.submit(\n {\n type: 'input',\n content: formatLick(lick),\n whenBusy: 'steer',\n requestId: `lick:${lick.id}`,\n },\n context\n );\n await harness.commit(async (tx) => {\n const doc = await tx.doc(LicksOutbox);\n doc.queues[key] = { submission: submission.id, pending: null };\n }, context);\n }\n\n async function flushAll(context: Context): Promise<void> {\n const { harness } = await host;\n const keys = Object.keys((await harness.snapshot(LicksOutbox, context))?.queues ?? {});\n for (const key of keys) await flushKey(key, context);\n }\n\n async function find(\n conversation: Conversation,\n id: string,\n context: Context\n ): Promise<LickFound | undefined> {\n const { entries } = await conversation.context(context);\n const lick = entries.map(entryLick).find((candidate) => candidate?.id === id);\n if (!lick) return undefined;\n return { lick, decision: lickDecisions(entries).get(id) };\n }\n\n return {\n deliver(event, context) {\n return serial(async () => {\n const { harness } = await host;\n const key = keyOf(event);\n await settled(key, context);\n const stream = `${event.channel}|${event.source}`;\n const now = event.at ?? Date.now();\n const accepted = await harness.commit(async (tx) => {\n const doc = await tx.doc(LicksOutbox);\n const seen = doc.events[stream] ?? [];\n if (event.eventId !== undefined) {\n if (seen.includes(event.eventId)) return false;\n doc.events[stream] = [...seen, event.eventId].slice(-MAX_EVENTS);\n }\n const queue = doc.queues[key] ?? { submission: null, pending: null };\n queue.pending = queue.pending\n ? merge(queue.pending, event, now)\n : fresh(event, now, actions(event.channel));\n doc.queues[key] = queue;\n return true;\n }, context);\n if (accepted) await flushKey(key, context);\n });\n },\n flush: (context) => serial(() => flushAll(context)),\n find,\n async decide(conversation, id, action, reason, context) {\n const found = await find(conversation, id, context);\n if (!found) throw new Error(`There is no lick ${id} in this conversation.`);\n if (found.decision) throw new Error(`Lick ${id} is already ${found.decision}.`);\n if (!found.lick.actions?.includes(action))\n throw new Error(`Lick ${id} (${found.lick.channel}) has no ${action} action.`);\n const run = handlers.get(found.lick.channel)?.[action];\n if (!run) throw new Error(`Lick ${id} (${found.lick.channel}) has no ${action} action.`);\n return (await run(found.lick, reason, context)) ?? `Lick ${id} ${action}ed.`;\n },\n handle(channel, handler) {\n handlers.set(channel, handler);\n },\n async pending(context) {\n const { harness } = await host;\n const queues = (await harness.snapshot(LicksOutbox, context))?.queues ?? {};\n return Object.values(queues).filter((queue) => queue.submission !== null || queue.pending)\n .length;\n },\n };\n}\n\nexport { LICK_STATE_KIND };\n"],
|
|
5
|
-
"mappings": "AACA;AAAA,EAEE;AAAA,OAGK;AACP;AAAA,EACE;AAAA,EAMA;AAAA,OACK;AACP,SAAS,WAAW,iBAAoC,qBAAqB;AAiCtE,MAAM,cAAc,UAAuB;AAAA,EAChD,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS,OAAO,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE;AAC3C,CAAC;
|
|
4
|
+
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport {\n type Conversation,\n defineDoc,\n type Harness,\n type SubmissionId,\n} from '@earendil-works/pi-durable';\nimport {\n formatLick,\n type Lick,\n type LickAction,\n type LickChannel,\n type LickSeverity,\n type LickTarget,\n lickId,\n} from './lick.ts';\nimport { entryLick, LICK_STATE_KIND, type LickDecision, lickDecisions } from './state.ts';\n\nexport interface LickEvent {\n channel: LickChannel;\n source: string;\n title: string;\n text: string;\n body?: string;\n items?: string[];\n count?: number;\n target: LickTarget;\n coalesce?: boolean;\n severity?: LickSeverity;\n eventId?: string;\n at?: number;\n}\n\ntype Pending = {\n lick: Lick;\n items: string[];\n body: string | null;\n};\n\ntype Queue = {\n submission: number | null;\n pending: Pending | null;\n};\n\ntype OutboxState = {\n queues: Record<string, Queue>;\n events: Record<string, string[]>;\n};\n\nexport const LicksOutbox = defineDoc<OutboxState>({\n kind: 'slicc.licks',\n version: 1,\n scope: 'session',\n initial: () => ({ queues: {}, events: {} }),\n});\n\nexport interface LickHandler {\n confirm?(lick: Lick, reason: string | undefined, context: Context): Promise<string | undefined>;\n dismiss?(lick: Lick, reason: string | undefined, context: Context): Promise<string | undefined>;\n}\n\nexport interface LickFound {\n lick: Lick;\n decision: LickDecision | undefined;\n}\n\nexport interface Licks {\n deliver(event: LickEvent, context: Context): Promise<void>;\n flush(context: Context): Promise<void>;\n find(conversation: Conversation, id: string, context: Context): Promise<LickFound | undefined>;\n decide(\n conversation: Conversation,\n id: string,\n action: LickAction,\n reason: string | undefined,\n context: Context\n ): Promise<string>;\n handle(channel: LickChannel, handler: LickHandler): void;\n pending(context: Context): Promise<number>;\n forget(target: LickTarget, channel: LickChannel, source: string, context: Context): Promise<void>;\n}\n\nexport interface LicksHost {\n harness: Harness;\n resolve(target: LickTarget, channel: LickChannel, context: Context): Promise<Conversation>;\n}\n\nexport const MAX_ITEMS = 50;\nexport const MAX_EVENTS = 64;\n\nexport function render(pending: Pending): Lick {\n const shown = pending.items.slice(0, MAX_ITEMS);\n const more = pending.items.length - shown.length;\n const lines = [\n ...(pending.body ? [pending.body] : []),\n ...shown,\n ...(more > 0 ? [`\u2026 and ${more} more`] : []),\n ];\n const { body: _, ...lick } = pending.lick;\n return lines.length ? { ...lick, body: lines.join('\\n') } : lick;\n}\n\nconst RANK: Record<LickSeverity, number> = { warn: 1, error: 2 };\n\nexport function strongest(\n a: LickSeverity | undefined,\n b: LickSeverity | undefined\n): LickSeverity | undefined {\n if (!a) return b;\n if (!b) return a;\n return RANK[b] > RANK[a] ? b : a;\n}\n\nfunction merge(pending: Pending, event: LickEvent, now: number): Pending {\n const items = [...pending.items];\n for (const item of event.items ?? []) if (!items.includes(item)) items.push(item);\n const { severity: _, ...lick } = pending.lick;\n const severity = strongest(pending.lick.severity, event.severity);\n return {\n lick: {\n ...lick,\n title: event.title,\n text: event.text,\n count: pending.lick.count + (event.count ?? 1),\n at: event.at ?? now,\n ...(severity ? { severity } : {}),\n },\n items,\n body: event.body ?? pending.body,\n };\n}\n\nfunction fresh(event: LickEvent, now: number, listed: LickAction[] | undefined): Pending {\n return {\n lick: {\n id: lickId(),\n channel: event.channel,\n source: event.source,\n title: event.title,\n text: event.text,\n count: event.count ?? 1,\n at: now,\n ...(listed ? { actions: listed } : {}),\n ...(event.severity ? { severity: event.severity } : {}),\n },\n items: [...new Set(event.items ?? [])],\n body: event.body ?? null,\n };\n}\n\nfunction keyOf(event: LickEvent): string {\n const base = `${event.target}|${event.channel}|${event.source}`;\n return event.coalesce === false ? `${base}|${event.eventId ?? lickId()}` : base;\n}\n\nexport function createLicks(host: Promise<LicksHost>): Licks {\n const handlers = new Map<LickChannel, LickHandler>();\n let lock: Promise<unknown> = Promise.resolve();\n const serial = <T>(operation: () => Promise<T>): Promise<T> => {\n const run = lock.then(operation, operation);\n lock = run.catch(() => undefined);\n return run;\n };\n\n const actions = (channel: LickChannel): LickAction[] | undefined => {\n const handler = handlers.get(channel);\n const list: LickAction[] = [];\n if (handler?.confirm) list.push('confirm');\n if (handler?.dismiss) list.push('dismiss');\n return list.length ? list : undefined;\n };\n\n async function previous(\n harness: Harness,\n id: number | null,\n context: Context\n ): Promise<'queued' | 'withdrawn' | 'gone'> {\n if (id === null) return 'gone';\n const submission = await harness.submission(id as SubmissionId, context);\n const record = await submission?.status(context);\n if (record?.status === 'queued') return 'queued';\n return record?.status === 'unanswered' && record.reason === 'aborted' ? 'withdrawn' : 'gone';\n }\n\n async function settled(key: string, context: Context): Promise<Queue | undefined> {\n const { harness } = await host;\n const queue = (await harness.snapshot(LicksOutbox, context))?.queues[key];\n if (!queue) return undefined;\n const before = await previous(harness, queue.submission, context);\n if (before === 'queued') return undefined;\n if (queue.pending && before === 'gone') return queue;\n await harness.commit(async (tx) => {\n const doc = await tx.doc(LicksOutbox);\n if (doc.queues[key]?.submission === queue.submission) delete doc.queues[key];\n }, context);\n return undefined;\n }\n\n async function flushKey(key: string, context: Context): Promise<void> {\n const { harness, resolve } = await host;\n const queue = await settled(key, context);\n if (!queue?.pending) return;\n const lick = render(queue.pending);\n const target = key.split('|')[0] as LickTarget;\n const conversation = await resolve(target, queue.pending.lick.channel, context);\n const submission = await conversation.submit(\n {\n type: 'input',\n content: formatLick(lick),\n whenBusy: 'steer',\n requestId: `lick:${lick.id}`,\n },\n context\n );\n await harness.commit(async (tx) => {\n const doc = await tx.doc(LicksOutbox);\n doc.queues[key] = { submission: submission.id, pending: null };\n }, context);\n }\n\n async function flushAll(context: Context): Promise<void> {\n const { harness } = await host;\n const keys = Object.keys((await harness.snapshot(LicksOutbox, context))?.queues ?? {});\n for (const key of keys) await flushKey(key, context);\n }\n\n async function find(\n conversation: Conversation,\n id: string,\n context: Context\n ): Promise<LickFound | undefined> {\n const { entries } = await conversation.context(context);\n const lick = entries.map(entryLick).find((candidate) => candidate?.id === id);\n if (!lick) return undefined;\n return { lick, decision: lickDecisions(entries).get(id) };\n }\n\n return {\n deliver(event, context) {\n return serial(async () => {\n const { harness } = await host;\n const key = keyOf(event);\n await settled(key, context);\n const stream = `${event.channel}|${event.source}`;\n const now = event.at ?? Date.now();\n const accepted = await harness.commit(async (tx) => {\n const doc = await tx.doc(LicksOutbox);\n const seen = doc.events[stream] ?? [];\n if (event.eventId !== undefined) {\n if (seen.includes(event.eventId)) return false;\n doc.events[stream] = [...seen, event.eventId].slice(-MAX_EVENTS);\n }\n const queue = doc.queues[key] ?? { submission: null, pending: null };\n queue.pending = queue.pending\n ? merge(queue.pending, event, now)\n : fresh(event, now, actions(event.channel));\n doc.queues[key] = queue;\n return true;\n }, context);\n if (accepted) await flushKey(key, context);\n });\n },\n flush: (context) => serial(() => flushAll(context)),\n find,\n async decide(conversation, id, action, reason, context) {\n const found = await find(conversation, id, context);\n if (!found) throw new Error(`There is no lick ${id} in this conversation.`);\n if (found.decision) throw new Error(`Lick ${id} is already ${found.decision}.`);\n if (!found.lick.actions?.includes(action))\n throw new Error(`Lick ${id} (${found.lick.channel}) has no ${action} action.`);\n const run = handlers.get(found.lick.channel)?.[action];\n if (!run) throw new Error(`Lick ${id} (${found.lick.channel}) has no ${action} action.`);\n return (await run(found.lick, reason, context)) ?? `Lick ${id} ${action}ed.`;\n },\n handle(channel, handler) {\n handlers.set(channel, handler);\n },\n forget(target, channel, source, context) {\n return serial(async () => {\n const { harness } = await host;\n const key = `${target}|${channel}|${source}`;\n await harness.commit(async (tx) => {\n const doc = await tx.doc(LicksOutbox);\n const queue = doc.queues[key];\n if (queue?.pending) queue.pending = null;\n }, context);\n });\n },\n async pending(context) {\n const { harness } = await host;\n const queues = (await harness.snapshot(LicksOutbox, context))?.queues ?? {};\n return Object.values(queues).filter((queue) => queue.submission !== null || queue.pending)\n .length;\n },\n };\n}\n\nexport { LICK_STATE_KIND };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/main.js
CHANGED
|
@@ -6,10 +6,13 @@ import { openAgent } from "./agent.js";
|
|
|
6
6
|
import { EncryptedCredentialStore } from "./credentials.js";
|
|
7
7
|
import { hostAgent } from "./host.js";
|
|
8
8
|
import { createActivity } from "./kernel/activity.js";
|
|
9
|
-
import { HOME, kernelEnvironment } from "./kernel/env.js";
|
|
9
|
+
import { HOME, kernelEnvironment, SliccKernelEnv } from "./kernel/env.js";
|
|
10
|
+
import { processGroups } from "./kernel/groups.js";
|
|
10
11
|
import { setupLicks } from "./licks/index.js";
|
|
11
12
|
import { transportFetch } from "./net.js";
|
|
12
13
|
import { sliccPrompt } from "./prompt.js";
|
|
14
|
+
import { identity } from "./scoops/identity.js";
|
|
15
|
+
import { setupScoops } from "./scoops/index.js";
|
|
13
16
|
import {
|
|
14
17
|
createAgentSettings,
|
|
15
18
|
createSliccModels,
|
|
@@ -36,30 +39,55 @@ async function start(scope, port, options) {
|
|
|
36
39
|
registry.install(CodingTools);
|
|
37
40
|
registry.install(sliccPrompt(facts));
|
|
38
41
|
const licks = setupLicks(registry);
|
|
42
|
+
const scoops = setupScoops(registry, licks.licks, CodingTools.tools);
|
|
39
43
|
const activity = createActivity();
|
|
40
|
-
const
|
|
44
|
+
const groups = processGroups(client);
|
|
45
|
+
const model = options.model ?? DEFAULT_MODEL;
|
|
46
|
+
let opened;
|
|
47
|
+
const environment = kernelEnvironment(client, {
|
|
48
|
+
activity,
|
|
49
|
+
groups,
|
|
50
|
+
identify: identity(() => opened?.agents, model)
|
|
51
|
+
});
|
|
41
52
|
const agent = await openAgent({
|
|
42
53
|
models,
|
|
43
|
-
model
|
|
54
|
+
model,
|
|
44
55
|
storage: await (options.storage ?? (() => openOpfsSqliteStorage()))(),
|
|
45
56
|
registry,
|
|
46
57
|
env: environment
|
|
47
58
|
});
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
activity
|
|
52
|
-
});
|
|
59
|
+
opened = agent;
|
|
60
|
+
const home = new SliccKernelEnv(client, { cwd: HOME });
|
|
61
|
+
const sources = licks.attach(agent, { env: home, home: HOME, activity });
|
|
53
62
|
await sources.start(BACKGROUND_CONTEXT);
|
|
54
63
|
await sources.boot(
|
|
55
64
|
{ version: facts.version, boot: await kernelBoot(client) },
|
|
56
65
|
BACKGROUND_CONTEXT
|
|
57
66
|
);
|
|
67
|
+
const runtime = await scoops.attach(
|
|
68
|
+
{
|
|
69
|
+
harness: agent.harness,
|
|
70
|
+
agents: agent.agents,
|
|
71
|
+
groups,
|
|
72
|
+
env: home,
|
|
73
|
+
home: HOME,
|
|
74
|
+
alive: alive(client),
|
|
75
|
+
...options.assets ? { assets: options.assets } : {}
|
|
76
|
+
},
|
|
77
|
+
BACKGROUND_CONTEXT
|
|
78
|
+
);
|
|
58
79
|
return hostAgent(agent, {
|
|
59
80
|
settings: await createAgentSettings(models, credentials, providers),
|
|
60
|
-
licks: { licks: licks.licks, sources }
|
|
81
|
+
licks: { licks: licks.licks, sources },
|
|
82
|
+
scoops: { scoops: scoops.scoops, runtime }
|
|
61
83
|
});
|
|
62
84
|
}
|
|
85
|
+
function alive(client) {
|
|
86
|
+
return async (pid) => {
|
|
87
|
+
if (!client.ps) return true;
|
|
88
|
+
return (await client.ps()).some((process) => process.pid === pid);
|
|
89
|
+
};
|
|
90
|
+
}
|
|
63
91
|
function runAgentWorker(scope, options = {}) {
|
|
64
92
|
const host = start(scope, kernelPort(scope), options);
|
|
65
93
|
host.catch(() => void 0);
|
|
@@ -67,6 +95,7 @@ function runAgentWorker(scope, options = {}) {
|
|
|
67
95
|
return host;
|
|
68
96
|
}
|
|
69
97
|
export {
|
|
98
|
+
alive,
|
|
70
99
|
runAgentWorker
|
|
71
100
|
};
|
|
72
101
|
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/main.ts"],
|
|
4
|
-
"sourcesContent": ["import { attachKernel } from '@ai-ecoverse/slicc-kernel';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { CredentialStore, Provider } from '@earendil-works/pi-ai';\nimport { createRegistry, type ModelRef, type Storage } from '@earendil-works/pi-durable';\nimport { CodingTools } from '@earendil-works/pi-durable/tools';\nimport { openAgent } from './agent.ts';\nimport { EncryptedCredentialStore } from './credentials.ts';\nimport { type AgentHost, hostAgent } from './host.ts';\nimport { createActivity } from './kernel/activity.ts';\nimport type { KernelClient } from './kernel/client.ts';\nimport { HOME, kernelEnvironment } from './kernel/env.ts';\nimport { setupLicks } from './licks/index.ts';\nimport { type Transport, transportFetch } from './net.ts';\nimport { sliccPrompt } from './prompt.ts';\nimport {\n createAgentSettings,\n createSliccModels,\n DEFAULT_MODEL,\n sliccProviders,\n} from './settings.ts';\nimport { openOpfsSqliteStorage } from './sqlite.ts';\nimport { agentVersion, commandsOnPath, kernelBoot, transportName } from './system.ts';\nimport { kernelPort, serveConnections, type WorkerScope } from './worker.ts';\n\nexport interface AgentWorkerScope extends WorkerScope {\n fetch: typeof fetch;\n location: { origin: string };\n}\n\nexport type KernelAttach = (port: MessagePort) => Promise<KernelClient & { transport: Transport }>;\n\nexport interface AgentWorkerOptions {\n model?: ModelRef;\n providers?: Provider[];\n attach?: KernelAttach;\n credentials?: () => Promise<CredentialStore>;\n storage?: () => Promise<Storage>;\n}\n\nasync function start(\n scope: AgentWorkerScope,\n port: Promise<MessagePort>,\n options: AgentWorkerOptions\n): Promise<AgentHost> {\n const attach: KernelAttach = options.attach ?? attachKernel;\n const client = await attach(await port);\n const native = scope.fetch.bind(scope);\n scope.fetch = transportFetch(client.transport, scope.location.origin, native);\n const facts = {\n version: await agentVersion((url) => native(url)),\n commands: await commandsOnPath(client),\n transport: transportName(client.transport),\n };\n const credentials = await (options.credentials ?? (() => EncryptedCredentialStore.open()))();\n const providers = options.providers ?? sliccProviders();\n const models = createSliccModels(credentials, providers);\n const registry = createRegistry();\n registry.install(CodingTools);\n registry.install(sliccPrompt(facts));\n const licks = setupLicks(registry);\n const activity = createActivity();\n const environment = kernelEnvironment(client, {
|
|
5
|
-
"mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AAEnC,SAAS,sBAAmD;AAC5D,SAAS,mBAAmB;AAC5B,
|
|
4
|
+
"sourcesContent": ["import { attachKernel } from '@ai-ecoverse/slicc-kernel';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { CredentialStore, Provider } from '@earendil-works/pi-ai';\nimport { createRegistry, type ModelRef, type Storage } from '@earendil-works/pi-durable';\nimport { CodingTools } from '@earendil-works/pi-durable/tools';\nimport { type Agent, openAgent } from './agent.ts';\nimport { EncryptedCredentialStore } from './credentials.ts';\nimport { type AgentHost, hostAgent } from './host.ts';\nimport { createActivity } from './kernel/activity.ts';\nimport type { KernelClient } from './kernel/client.ts';\nimport { HOME, kernelEnvironment, SliccKernelEnv } from './kernel/env.ts';\nimport { processGroups } from './kernel/groups.ts';\nimport { setupLicks } from './licks/index.ts';\nimport { type Transport, transportFetch } from './net.ts';\nimport { sliccPrompt } from './prompt.ts';\nimport { identity } from './scoops/identity.ts';\nimport { type Assets, setupScoops } from './scoops/index.ts';\nimport {\n createAgentSettings,\n createSliccModels,\n DEFAULT_MODEL,\n sliccProviders,\n} from './settings.ts';\nimport { openOpfsSqliteStorage } from './sqlite.ts';\nimport { agentVersion, commandsOnPath, kernelBoot, transportName } from './system.ts';\nimport { kernelPort, serveConnections, type WorkerScope } from './worker.ts';\n\nexport interface AgentWorkerScope extends WorkerScope {\n fetch: typeof fetch;\n location: { origin: string };\n}\n\nexport type KernelAttach = (port: MessagePort) => Promise<KernelClient & { transport: Transport }>;\n\nexport interface AgentWorkerOptions {\n model?: ModelRef;\n providers?: Provider[];\n attach?: KernelAttach;\n credentials?: () => Promise<CredentialStore>;\n storage?: () => Promise<Storage>;\n assets?: Assets;\n}\n\nasync function start(\n scope: AgentWorkerScope,\n port: Promise<MessagePort>,\n options: AgentWorkerOptions\n): Promise<AgentHost> {\n const attach: KernelAttach = options.attach ?? attachKernel;\n const client = await attach(await port);\n const native = scope.fetch.bind(scope);\n scope.fetch = transportFetch(client.transport, scope.location.origin, native);\n const facts = {\n version: await agentVersion((url) => native(url)),\n commands: await commandsOnPath(client),\n transport: transportName(client.transport),\n };\n const credentials = await (options.credentials ?? (() => EncryptedCredentialStore.open()))();\n const providers = options.providers ?? sliccProviders();\n const models = createSliccModels(credentials, providers);\n const registry = createRegistry();\n registry.install(CodingTools);\n registry.install(sliccPrompt(facts));\n const licks = setupLicks(registry);\n const scoops = setupScoops(registry, licks.licks, CodingTools.tools);\n const activity = createActivity();\n const groups = processGroups(client);\n const model = options.model ?? DEFAULT_MODEL;\n let opened: Agent | undefined;\n const environment = kernelEnvironment(client, {\n activity,\n groups,\n identify: identity(() => opened?.agents, model),\n });\n const agent = await openAgent({\n models,\n model,\n storage: await (options.storage ?? (() => openOpfsSqliteStorage()))(),\n registry,\n env: environment,\n });\n opened = agent;\n const home = new SliccKernelEnv(client, { cwd: HOME });\n const sources = licks.attach(agent, { env: home, home: HOME, activity });\n await sources.start(BACKGROUND_CONTEXT);\n await sources.boot(\n { version: facts.version, boot: await kernelBoot(client) },\n BACKGROUND_CONTEXT\n );\n const runtime = await scoops.attach(\n {\n harness: agent.harness,\n agents: agent.agents,\n groups,\n env: home,\n home: HOME,\n alive: alive(client),\n ...(options.assets ? { assets: options.assets } : {}),\n },\n BACKGROUND_CONTEXT\n );\n return hostAgent(agent, {\n settings: await createAgentSettings(models, credentials, providers),\n licks: { licks: licks.licks, sources },\n scoops: { scoops: scoops.scoops, runtime },\n });\n}\n\nexport function alive(client: KernelClient) {\n return async (pid: number): Promise<boolean> => {\n if (!client.ps) return true;\n return (await client.ps()).some((process) => process.pid === pid);\n };\n}\n\nexport function runAgentWorker(\n scope: AgentWorkerScope,\n options: AgentWorkerOptions = {}\n): Promise<AgentHost> {\n const host = start(scope, kernelPort(scope), options);\n host.catch(() => undefined);\n serveConnections(scope, host);\n return host;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
function unquote(value) {
|
|
2
|
+
const quoted = /^(["'])(.*)\1$/s.exec(value);
|
|
3
|
+
if (!quoted) return value;
|
|
4
|
+
return quoted[1] === '"' ? quoted[2].replace(/\\(["\\])/g, "$1") : quoted[2].replace(/''/g, "'");
|
|
5
|
+
}
|
|
6
|
+
function scalar(raw) {
|
|
7
|
+
const value = raw.trim();
|
|
8
|
+
if (/^\[.*\]$/s.test(value))
|
|
9
|
+
return value.slice(1, -1).split(",").map((item) => unquote(item.trim())).filter(Boolean);
|
|
10
|
+
if (value === "true" || value === "false") return value === "true";
|
|
11
|
+
if (/^-?\d+(\.\d+)?$/.test(value)) return Number(value);
|
|
12
|
+
return unquote(value);
|
|
13
|
+
}
|
|
14
|
+
function parseFrontmatter(text) {
|
|
15
|
+
const normalized = text.replace(/\r\n/g, "\n");
|
|
16
|
+
const match = /^---\n([\s\S]*?)\n---(?:\n|$)/.exec(normalized);
|
|
17
|
+
if (!match)
|
|
18
|
+
return { fields: {}, body: normalized.trim(), problems: ["no frontmatter between --- lines"] };
|
|
19
|
+
const fields = {};
|
|
20
|
+
const problems = [];
|
|
21
|
+
let list;
|
|
22
|
+
const nested = /* @__PURE__ */ new Set();
|
|
23
|
+
for (const line of match[1].split("\n")) {
|
|
24
|
+
if (!line.trim() || line.trimStart().startsWith("#")) continue;
|
|
25
|
+
const item = /^\s+-\s+(.*)$/.exec(line);
|
|
26
|
+
if (item && list) {
|
|
27
|
+
fields[list].push(unquote(item[1].trim()));
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (/^\s/.test(line) && list) {
|
|
31
|
+
nested.add(list);
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const pair = /^([A-Za-z][\w-]*):(?:\s+(.*))?$/.exec(line);
|
|
35
|
+
if (!pair) {
|
|
36
|
+
problems.push(`can't read the line "${line.trim()}"`);
|
|
37
|
+
list = void 0;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const key = pair[1];
|
|
41
|
+
const value = pair[2]?.trim() ?? "";
|
|
42
|
+
if (value === "") {
|
|
43
|
+
fields[key] = [];
|
|
44
|
+
list = key;
|
|
45
|
+
} else {
|
|
46
|
+
fields[key] = scalar(value);
|
|
47
|
+
list = void 0;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
for (const key of nested) {
|
|
51
|
+
delete fields[key];
|
|
52
|
+
problems.push(`"${key}" has nested values, which SLICC doesn't read`);
|
|
53
|
+
}
|
|
54
|
+
return { fields, body: normalized.slice(match[0].length).trim(), problems };
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
parseFrontmatter
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=frontmatter.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/roles/frontmatter.ts"],
|
|
4
|
+
"sourcesContent": ["export type FrontmatterValue = string | number | boolean | string[];\n\nexport interface Frontmatter {\n fields: Record<string, FrontmatterValue>;\n body: string;\n problems: string[];\n}\n\nfunction unquote(value: string): string {\n const quoted = /^([\"'])(.*)\\1$/s.exec(value);\n if (!quoted) return value;\n return quoted[1] === '\"'\n ? (quoted[2] as string).replace(/\\\\([\"\\\\])/g, '$1')\n : (quoted[2] as string).replace(/''/g, \"'\");\n}\n\nfunction scalar(raw: string): FrontmatterValue {\n const value = raw.trim();\n if (/^\\[.*\\]$/s.test(value))\n return value\n .slice(1, -1)\n .split(',')\n .map((item) => unquote(item.trim()))\n .filter(Boolean);\n if (value === 'true' || value === 'false') return value === 'true';\n if (/^-?\\d+(\\.\\d+)?$/.test(value)) return Number(value);\n return unquote(value);\n}\n\nexport function parseFrontmatter(text: string): Frontmatter {\n const normalized = text.replace(/\\r\\n/g, '\\n');\n const match = /^---\\n([\\s\\S]*?)\\n---(?:\\n|$)/.exec(normalized);\n if (!match)\n return { fields: {}, body: normalized.trim(), problems: ['no frontmatter between --- lines'] };\n const fields: Record<string, FrontmatterValue> = {};\n const problems: string[] = [];\n let list: string | undefined;\n const nested = new Set<string>();\n for (const line of (match[1] as string).split('\\n')) {\n if (!line.trim() || line.trimStart().startsWith('#')) continue;\n const item = /^\\s+-\\s+(.*)$/.exec(line);\n if (item && list) {\n (fields[list] as string[]).push(unquote((item[1] as string).trim()));\n continue;\n }\n if (/^\\s/.test(line) && list) {\n nested.add(list);\n continue;\n }\n const pair = /^([A-Za-z][\\w-]*):(?:\\s+(.*))?$/.exec(line);\n if (!pair) {\n problems.push(`can't read the line \"${line.trim()}\"`);\n list = undefined;\n continue;\n }\n const key = pair[1] as string;\n const value = pair[2]?.trim() ?? '';\n if (value === '') {\n fields[key] = [];\n list = key;\n } else {\n fields[key] = scalar(value);\n list = undefined;\n }\n }\n for (const key of nested) {\n delete fields[key];\n problems.push(`\"${key}\" has nested values, which SLICC doesn't read`);\n }\n return { fields, body: normalized.slice(match[0].length).trim(), problems };\n}\n"],
|
|
5
|
+
"mappings": "AAQA,SAAS,QAAQ,OAAuB;AACtC,QAAM,SAAS,kBAAkB,KAAK,KAAK;AAC3C,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,OAAO,CAAC,MAAM,MAChB,OAAO,CAAC,EAAa,QAAQ,cAAc,IAAI,IAC/C,OAAO,CAAC,EAAa,QAAQ,OAAO,GAAG;AAC9C;AAEA,SAAS,OAAO,KAA+B;AAC7C,QAAM,QAAQ,IAAI,KAAK;AACvB,MAAI,YAAY,KAAK,KAAK;AACxB,WAAO,MACJ,MAAM,GAAG,EAAE,EACX,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,QAAQ,KAAK,KAAK,CAAC,CAAC,EAClC,OAAO,OAAO;AACnB,MAAI,UAAU,UAAU,UAAU,QAAS,QAAO,UAAU;AAC5D,MAAI,kBAAkB,KAAK,KAAK,EAAG,QAAO,OAAO,KAAK;AACtD,SAAO,QAAQ,KAAK;AACtB;AAEO,SAAS,iBAAiB,MAA2B;AAC1D,QAAM,aAAa,KAAK,QAAQ,SAAS,IAAI;AAC7C,QAAM,QAAQ,gCAAgC,KAAK,UAAU;AAC7D,MAAI,CAAC;AACH,WAAO,EAAE,QAAQ,CAAC,GAAG,MAAM,WAAW,KAAK,GAAG,UAAU,CAAC,kCAAkC,EAAE;AAC/F,QAAM,SAA2C,CAAC;AAClD,QAAM,WAAqB,CAAC;AAC5B,MAAI;AACJ,QAAM,SAAS,oBAAI,IAAY;AAC/B,aAAW,QAAS,MAAM,CAAC,EAAa,MAAM,IAAI,GAAG;AACnD,QAAI,CAAC,KAAK,KAAK,KAAK,KAAK,UAAU,EAAE,WAAW,GAAG,EAAG;AACtD,UAAM,OAAO,gBAAgB,KAAK,IAAI;AACtC,QAAI,QAAQ,MAAM;AAChB,MAAC,OAAO,IAAI,EAAe,KAAK,QAAS,KAAK,CAAC,EAAa,KAAK,CAAC,CAAC;AACnE;AAAA,IACF;AACA,QAAI,MAAM,KAAK,IAAI,KAAK,MAAM;AAC5B,aAAO,IAAI,IAAI;AACf;AAAA,IACF;AACA,UAAM,OAAO,kCAAkC,KAAK,IAAI;AACxD,QAAI,CAAC,MAAM;AACT,eAAS,KAAK,wBAAwB,KAAK,KAAK,CAAC,GAAG;AACpD,aAAO;AACP;AAAA,IACF;AACA,UAAM,MAAM,KAAK,CAAC;AAClB,UAAM,QAAQ,KAAK,CAAC,GAAG,KAAK,KAAK;AACjC,QAAI,UAAU,IAAI;AAChB,aAAO,GAAG,IAAI,CAAC;AACf,aAAO;AAAA,IACT,OAAO;AACL,aAAO,GAAG,IAAI,OAAO,KAAK;AAC1B,aAAO;AAAA,IACT;AAAA,EACF;AACA,aAAW,OAAO,QAAQ;AACxB,WAAO,OAAO,GAAG;AACjB,aAAS,KAAK,IAAI,GAAG,+CAA+C;AAAA,EACtE;AACA,SAAO,EAAE,QAAQ,MAAM,WAAW,MAAM,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,GAAG,SAAS;AAC5E;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { parseFrontmatter } from "./frontmatter.js";
|
|
2
|
+
const DEFAULT_LIMITS = { maxLiveScoops: 16, maxPerTurn: 64 };
|
|
3
|
+
const TOOLS = {
|
|
4
|
+
read: "read",
|
|
5
|
+
write: "write",
|
|
6
|
+
edit: "edit",
|
|
7
|
+
bash: "bash",
|
|
8
|
+
grep: "bash",
|
|
9
|
+
find: "bash",
|
|
10
|
+
ls: "bash"
|
|
11
|
+
};
|
|
12
|
+
const THINKING = /* @__PURE__ */ new Set(["off", "minimal", "low", "medium", "high", "xhigh"]);
|
|
13
|
+
const APPLIED = /* @__PURE__ */ new Set([
|
|
14
|
+
"name",
|
|
15
|
+
"description",
|
|
16
|
+
"tools",
|
|
17
|
+
"model",
|
|
18
|
+
"thinking",
|
|
19
|
+
"systemPromptMode",
|
|
20
|
+
"aliases",
|
|
21
|
+
"output",
|
|
22
|
+
"package",
|
|
23
|
+
"advertise",
|
|
24
|
+
"inheritProjectContext",
|
|
25
|
+
"inheritSkills",
|
|
26
|
+
"skills",
|
|
27
|
+
"defaultReads"
|
|
28
|
+
]);
|
|
29
|
+
const LATER = {
|
|
30
|
+
memory: "per-agent memory comes with SLICC\u2019s memory panel"
|
|
31
|
+
};
|
|
32
|
+
function list(value) {
|
|
33
|
+
if (Array.isArray(value)) return value;
|
|
34
|
+
if (typeof value === "string")
|
|
35
|
+
return value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
function tools(names, where, warnings) {
|
|
39
|
+
const mapped = [];
|
|
40
|
+
for (const name of names) {
|
|
41
|
+
const tool = TOOLS[name];
|
|
42
|
+
if (tool) {
|
|
43
|
+
if (!mapped.includes(tool)) mapped.push(tool);
|
|
44
|
+
} else warnings.push(`${where}: tool "${name}" isn't available in SLICC; it's left out`);
|
|
45
|
+
}
|
|
46
|
+
return mapped;
|
|
47
|
+
}
|
|
48
|
+
function parseRole(text, source, path, warnings) {
|
|
49
|
+
const { fields, body, problems } = parseFrontmatter(text);
|
|
50
|
+
for (const problem of problems) warnings.push(`${path}: ${problem}`);
|
|
51
|
+
const name = fields.name;
|
|
52
|
+
const description = fields.description;
|
|
53
|
+
if (typeof name !== "string" || typeof description !== "string") {
|
|
54
|
+
warnings.push(`${path}: an agent file needs a name and a description; skipped`);
|
|
55
|
+
return void 0;
|
|
56
|
+
}
|
|
57
|
+
for (const key of Object.keys(fields))
|
|
58
|
+
if (!APPLIED.has(key))
|
|
59
|
+
warnings.push(
|
|
60
|
+
`${path}: "${key}" ${LATER[key] ? `is not read yet (${LATER[key]})` : "isn't supported in SLICC; it's ignored"}`
|
|
61
|
+
);
|
|
62
|
+
const thinking = typeof fields.thinking === "string" && THINKING.has(fields.thinking) ? fields.thinking : void 0;
|
|
63
|
+
if (fields.thinking !== void 0 && !thinking)
|
|
64
|
+
warnings.push(`${path}: thinking "${String(fields.thinking)}" is unknown; ignored`);
|
|
65
|
+
const pkg = typeof fields.package === "string" && fields.package ? `${fields.package}.` : "";
|
|
66
|
+
return {
|
|
67
|
+
name: `${pkg}${name}`,
|
|
68
|
+
description,
|
|
69
|
+
prompt: body,
|
|
70
|
+
mode: fields.systemPromptMode === "append" ? "append" : "replace",
|
|
71
|
+
...fields.tools !== void 0 ? { tools: tools(list(fields.tools), path, warnings) } : {},
|
|
72
|
+
...typeof fields.model === "string" ? { model: fields.model } : {},
|
|
73
|
+
...thinking ? { thinking } : {},
|
|
74
|
+
aliases: list(fields.aliases),
|
|
75
|
+
...typeof fields.output === "string" ? { output: fields.output } : {},
|
|
76
|
+
source,
|
|
77
|
+
path
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
async function markdown(files, dir, context, depth = 0) {
|
|
81
|
+
if (dir.endsWith(".md")) return [dir];
|
|
82
|
+
const listed = await files.listDir(dir, context);
|
|
83
|
+
if (!listed.ok || depth > 4) return [];
|
|
84
|
+
const out = [];
|
|
85
|
+
for (const info of listed.value) {
|
|
86
|
+
const path = `${dir}/${info.name}`;
|
|
87
|
+
if (info.kind === "directory") out.push(...await markdown(files, path, context, depth + 1));
|
|
88
|
+
else if (info.name.endsWith(".md") && !info.name.endsWith(".chain.md")) out.push(path);
|
|
89
|
+
}
|
|
90
|
+
return out.sort();
|
|
91
|
+
}
|
|
92
|
+
function positive(value, fallback) {
|
|
93
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : fallback;
|
|
94
|
+
}
|
|
95
|
+
async function settings(files, path, context, warnings) {
|
|
96
|
+
const read = await files.readTextFile(path, context);
|
|
97
|
+
const empty = { overrides: {}, limits: { ...DEFAULT_LIMITS } };
|
|
98
|
+
if (!read.ok) return empty;
|
|
99
|
+
let parsed;
|
|
100
|
+
try {
|
|
101
|
+
parsed = JSON.parse(read.value);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
warnings.push(`${path}: not valid JSON (${error.message}); overrides ignored`);
|
|
104
|
+
return empty;
|
|
105
|
+
}
|
|
106
|
+
const subagents = parsed.subagents ?? {};
|
|
107
|
+
return {
|
|
108
|
+
overrides: subagents.agentOverrides ?? {},
|
|
109
|
+
limits: {
|
|
110
|
+
maxLiveScoops: positive(subagents.maxLiveScoops, DEFAULT_LIMITS.maxLiveScoops),
|
|
111
|
+
maxPerTurn: positive(subagents.maxPerTurn, DEFAULT_LIMITS.maxPerTurn)
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function apply(role, override, warnings) {
|
|
116
|
+
if (!override) return role;
|
|
117
|
+
if (override.disabled === true) return void 0;
|
|
118
|
+
const next = { ...role };
|
|
119
|
+
if (typeof override.model === "string") next.model = override.model;
|
|
120
|
+
if (typeof override.thinking === "string" && THINKING.has(override.thinking))
|
|
121
|
+
next.thinking = override.thinking;
|
|
122
|
+
if (typeof override.description === "string") next.description = override.description;
|
|
123
|
+
if (typeof override.systemPrompt === "string") next.prompt = override.systemPrompt;
|
|
124
|
+
if (Array.isArray(override.tools))
|
|
125
|
+
next.tools = tools(override.tools.map(String), `override for ${role.name}`, warnings);
|
|
126
|
+
return next;
|
|
127
|
+
}
|
|
128
|
+
const ORDER = ["builtin", "package", "user", "project"];
|
|
129
|
+
async function loadRoles(options, context) {
|
|
130
|
+
const warnings = [];
|
|
131
|
+
const byName = /* @__PURE__ */ new Map();
|
|
132
|
+
const add = (role) => {
|
|
133
|
+
if (role) byName.set(role.name, role);
|
|
134
|
+
};
|
|
135
|
+
for (const { path, text } of await options.builtin())
|
|
136
|
+
add(parseRole(text, "builtin", path, warnings));
|
|
137
|
+
const dirs = [...options.dirs].sort((a, b) => ORDER.indexOf(a.source) - ORDER.indexOf(b.source));
|
|
138
|
+
for (const { source, dir } of dirs)
|
|
139
|
+
for (const path of await markdown(options.files, dir, context)) {
|
|
140
|
+
const read = await options.files.readTextFile(path, context);
|
|
141
|
+
if (read.ok) add(parseRole(read.value, source, path, warnings));
|
|
142
|
+
}
|
|
143
|
+
const { overrides, limits } = await settings(
|
|
144
|
+
options.files,
|
|
145
|
+
options.settingsPath,
|
|
146
|
+
context,
|
|
147
|
+
warnings
|
|
148
|
+
);
|
|
149
|
+
const roles = [];
|
|
150
|
+
for (const role of byName.values()) {
|
|
151
|
+
const applied = apply(role, overrides[role.name], warnings);
|
|
152
|
+
if (applied) roles.push(applied);
|
|
153
|
+
}
|
|
154
|
+
return { roles, warnings, limits };
|
|
155
|
+
}
|
|
156
|
+
function findRole(roles, name) {
|
|
157
|
+
return roles.find((role) => role.name === name) ?? roles.find((role) => role.aliases.includes(name));
|
|
158
|
+
}
|
|
159
|
+
async function manifestDirs(files, root, context) {
|
|
160
|
+
const top = await files.listDir(root, context);
|
|
161
|
+
if (!top.ok) return [];
|
|
162
|
+
const out = [];
|
|
163
|
+
for (const entry of top.value) {
|
|
164
|
+
if (entry.kind !== "directory" || entry.name.startsWith(".")) continue;
|
|
165
|
+
if (!entry.name.startsWith("@")) {
|
|
166
|
+
out.push(`${root}/${entry.name}`);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
const scoped = await files.listDir(`${root}/${entry.name}`, context);
|
|
170
|
+
if (scoped.ok) {
|
|
171
|
+
for (const inner of scoped.value)
|
|
172
|
+
if (inner.kind === "directory") out.push(`${root}/${entry.name}/${inner.name}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
function agentPaths(dir, text) {
|
|
178
|
+
let manifest;
|
|
179
|
+
try {
|
|
180
|
+
manifest = JSON.parse(text);
|
|
181
|
+
} catch {
|
|
182
|
+
return [];
|
|
183
|
+
}
|
|
184
|
+
const agents = manifest["pi-subagents"]?.agents ?? manifest.pi?.subagents?.agents;
|
|
185
|
+
const listed = Array.isArray(agents) ? agents : typeof agents === "string" ? [agents] : [];
|
|
186
|
+
return listed.filter((path) => typeof path === "string").map((path) => `${dir}/${path.replace(/^\.\//, "").replace(/\/$/, "")}`);
|
|
187
|
+
}
|
|
188
|
+
async function packageDirs(files, root, context) {
|
|
189
|
+
const out = [];
|
|
190
|
+
for (const dir of await manifestDirs(files, root, context)) {
|
|
191
|
+
const read = await files.readTextFile(`${dir}/package.json`, context);
|
|
192
|
+
if (read.ok) out.push(...agentPaths(dir, read.value));
|
|
193
|
+
}
|
|
194
|
+
return out;
|
|
195
|
+
}
|
|
196
|
+
export {
|
|
197
|
+
DEFAULT_LIMITS,
|
|
198
|
+
agentPaths,
|
|
199
|
+
findRole,
|
|
200
|
+
loadRoles,
|
|
201
|
+
packageDirs,
|
|
202
|
+
parseRole
|
|
203
|
+
};
|
|
204
|
+
//# sourceMappingURL=roles.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/roles/roles.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport { type FrontmatterValue, parseFrontmatter } from './frontmatter.ts';\n\nexport type RoleSource = 'builtin' | 'package' | 'user' | 'project';\nexport type Thinking = 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh';\n\nexport interface Role {\n name: string;\n description: string;\n prompt: string;\n mode: 'replace' | 'append';\n tools?: string[];\n model?: string;\n thinking?: Thinking;\n aliases: string[];\n output?: string;\n source: RoleSource;\n path: string;\n}\n\nexport interface Roles {\n roles: Role[];\n warnings: string[];\n limits: { maxLiveScoops: number; maxPerTurn: number };\n}\n\nexport const DEFAULT_LIMITS = { maxLiveScoops: 16, maxPerTurn: 64 };\n\nconst TOOLS: Record<string, string> = {\n read: 'read',\n write: 'write',\n edit: 'edit',\n bash: 'bash',\n grep: 'bash',\n find: 'bash',\n ls: 'bash',\n};\n\nconst THINKING = new Set<string>(['off', 'minimal', 'low', 'medium', 'high', 'xhigh']);\n\nconst APPLIED = new Set([\n 'name',\n 'description',\n 'tools',\n 'model',\n 'thinking',\n 'systemPromptMode',\n 'aliases',\n 'output',\n 'package',\n 'advertise',\n 'inheritProjectContext',\n 'inheritSkills',\n 'skills',\n 'defaultReads',\n]);\n\nconst LATER: Record<string, string> = {\n memory: 'per-agent memory comes with SLICC\u2019s memory panel',\n};\n\nexport type RoleFiles = Pick<ExecutionEnv, 'readTextFile' | 'listDir'>;\n\nexport interface RoleSourceDir {\n source: RoleSource;\n dir: string;\n}\n\nfunction list(value: FrontmatterValue | undefined): string[] {\n if (Array.isArray(value)) return value;\n if (typeof value === 'string')\n return value\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean);\n return [];\n}\n\nfunction tools(names: string[], where: string, warnings: string[]): string[] {\n const mapped: string[] = [];\n for (const name of names) {\n const tool = TOOLS[name];\n if (tool) {\n if (!mapped.includes(tool)) mapped.push(tool);\n } else warnings.push(`${where}: tool \"${name}\" isn't available in SLICC; it's left out`);\n }\n return mapped;\n}\n\nexport function parseRole(\n text: string,\n source: RoleSource,\n path: string,\n warnings: string[]\n): Role | undefined {\n const { fields, body, problems } = parseFrontmatter(text);\n for (const problem of problems) warnings.push(`${path}: ${problem}`);\n const name = fields.name;\n const description = fields.description;\n if (typeof name !== 'string' || typeof description !== 'string') {\n warnings.push(`${path}: an agent file needs a name and a description; skipped`);\n return undefined;\n }\n for (const key of Object.keys(fields))\n if (!APPLIED.has(key))\n warnings.push(\n `${path}: \"${key}\" ${LATER[key] ? `is not read yet (${LATER[key]})` : \"isn't supported in SLICC; it's ignored\"}`\n );\n const thinking =\n typeof fields.thinking === 'string' && THINKING.has(fields.thinking)\n ? (fields.thinking as Thinking)\n : undefined;\n if (fields.thinking !== undefined && !thinking)\n warnings.push(`${path}: thinking \"${String(fields.thinking)}\" is unknown; ignored`);\n const pkg = typeof fields.package === 'string' && fields.package ? `${fields.package}.` : '';\n return {\n name: `${pkg}${name}`,\n description,\n prompt: body,\n mode: fields.systemPromptMode === 'append' ? 'append' : 'replace',\n ...(fields.tools !== undefined ? { tools: tools(list(fields.tools), path, warnings) } : {}),\n ...(typeof fields.model === 'string' ? { model: fields.model } : {}),\n ...(thinking ? { thinking } : {}),\n aliases: list(fields.aliases),\n ...(typeof fields.output === 'string' ? { output: fields.output } : {}),\n source,\n path,\n };\n}\n\nasync function markdown(\n files: RoleFiles,\n dir: string,\n context: Context,\n depth = 0\n): Promise<string[]> {\n if (dir.endsWith('.md')) return [dir];\n const listed = await files.listDir(dir, context);\n if (!listed.ok || depth > 4) return [];\n const out: string[] = [];\n for (const info of listed.value) {\n const path = `${dir}/${info.name}`;\n if (info.kind === 'directory') out.push(...(await markdown(files, path, context, depth + 1)));\n else if (info.name.endsWith('.md') && !info.name.endsWith('.chain.md')) out.push(path);\n }\n return out.sort();\n}\n\ntype Override = {\n model?: unknown;\n thinking?: unknown;\n tools?: unknown;\n systemPrompt?: unknown;\n description?: unknown;\n disabled?: unknown;\n};\n\ninterface Settings {\n overrides: Record<string, Override>;\n limits: Roles['limits'];\n}\n\nfunction positive(value: unknown, fallback: number): number {\n return typeof value === 'number' && Number.isInteger(value) && value > 0 ? value : fallback;\n}\n\nasync function settings(\n files: RoleFiles,\n path: string,\n context: Context,\n warnings: string[]\n): Promise<Settings> {\n const read = await files.readTextFile(path, context);\n const empty = { overrides: {}, limits: { ...DEFAULT_LIMITS } };\n if (!read.ok) return empty;\n let parsed: {\n subagents?: {\n agentOverrides?: Record<string, Override>;\n maxLiveScoops?: unknown;\n maxPerTurn?: unknown;\n };\n };\n try {\n parsed = JSON.parse(read.value);\n } catch (error) {\n warnings.push(`${path}: not valid JSON (${(error as Error).message}); overrides ignored`);\n return empty;\n }\n const subagents = parsed.subagents ?? {};\n return {\n overrides: subagents.agentOverrides ?? {},\n limits: {\n maxLiveScoops: positive(subagents.maxLiveScoops, DEFAULT_LIMITS.maxLiveScoops),\n maxPerTurn: positive(subagents.maxPerTurn, DEFAULT_LIMITS.maxPerTurn),\n },\n };\n}\n\nfunction apply(role: Role, override: Override | undefined, warnings: string[]): Role | undefined {\n if (!override) return role;\n if (override.disabled === true) return undefined;\n const next: Role = { ...role };\n if (typeof override.model === 'string') next.model = override.model;\n if (typeof override.thinking === 'string' && THINKING.has(override.thinking))\n next.thinking = override.thinking as Thinking;\n if (typeof override.description === 'string') next.description = override.description;\n if (typeof override.systemPrompt === 'string') next.prompt = override.systemPrompt;\n if (Array.isArray(override.tools))\n next.tools = tools(override.tools.map(String), `override for ${role.name}`, warnings);\n return next;\n}\n\nexport interface LoadOptions {\n files: RoleFiles;\n builtin: () => Promise<{ path: string; text: string }[]>;\n dirs: RoleSourceDir[];\n settingsPath: string;\n}\n\nconst ORDER: RoleSource[] = ['builtin', 'package', 'user', 'project'];\n\nexport async function loadRoles(options: LoadOptions, context: Context): Promise<Roles> {\n const warnings: string[] = [];\n const byName = new Map<string, Role>();\n const add = (role: Role | undefined) => {\n if (role) byName.set(role.name, role);\n };\n for (const { path, text } of await options.builtin())\n add(parseRole(text, 'builtin', path, warnings));\n const dirs = [...options.dirs].sort((a, b) => ORDER.indexOf(a.source) - ORDER.indexOf(b.source));\n for (const { source, dir } of dirs)\n for (const path of await markdown(options.files, dir, context)) {\n const read = await options.files.readTextFile(path, context);\n if (read.ok) add(parseRole(read.value, source, path, warnings));\n }\n const { overrides, limits } = await settings(\n options.files,\n options.settingsPath,\n context,\n warnings\n );\n const roles: Role[] = [];\n for (const role of byName.values()) {\n const applied = apply(role, overrides[role.name], warnings);\n if (applied) roles.push(applied);\n }\n return { roles, warnings, limits };\n}\n\nexport function findRole(roles: readonly Role[], name: string): Role | undefined {\n return (\n roles.find((role) => role.name === name) ?? roles.find((role) => role.aliases.includes(name))\n );\n}\n\nasync function manifestDirs(files: RoleFiles, root: string, context: Context): Promise<string[]> {\n const top = await files.listDir(root, context);\n if (!top.ok) return [];\n const out: string[] = [];\n for (const entry of top.value) {\n if (entry.kind !== 'directory' || entry.name.startsWith('.')) continue;\n if (!entry.name.startsWith('@')) {\n out.push(`${root}/${entry.name}`);\n continue;\n }\n const scoped = await files.listDir(`${root}/${entry.name}`, context);\n if (scoped.ok)\n for (const inner of scoped.value)\n if (inner.kind === 'directory') out.push(`${root}/${entry.name}/${inner.name}`);\n }\n return out;\n}\n\ntype Manifest = {\n 'pi-subagents'?: { agents?: unknown };\n pi?: { subagents?: { agents?: unknown } };\n};\n\nexport function agentPaths(dir: string, text: string): string[] {\n let manifest: Manifest;\n try {\n manifest = JSON.parse(text) as Manifest;\n } catch {\n return [];\n }\n const agents = manifest['pi-subagents']?.agents ?? manifest.pi?.subagents?.agents;\n const listed = Array.isArray(agents) ? agents : typeof agents === 'string' ? [agents] : [];\n return listed\n .filter((path): path is string => typeof path === 'string')\n .map((path) => `${dir}/${path.replace(/^\\.\\//, '').replace(/\\/$/, '')}`);\n}\n\nexport async function packageDirs(\n files: RoleFiles,\n root: string,\n context: Context\n): Promise<string[]> {\n const out: string[] = [];\n for (const dir of await manifestDirs(files, root, context)) {\n const read = await files.readTextFile(`${dir}/package.json`, context);\n if (read.ok) out.push(...agentPaths(dir, read.value));\n }\n return out;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|