@ai-ecoverse/slicc-agent 3.33.0 → 3.35.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 +24 -2
- package/bin/agent +1 -1
- package/dist/host.js +2 -0
- package/dist/host.js.map +2 -2
- package/dist/index.js +14 -1
- package/dist/index.js.map +2 -2
- package/dist/kernel/users.js +113 -0
- package/dist/kernel/users.js.map +7 -0
- package/dist/main.js +46 -21
- package/dist/main.js.map +2 -2
- package/dist/models/index.js +182 -0
- package/dist/models/index.js.map +7 -0
- package/dist/owner.js +19 -2
- package/dist/owner.js.map +2 -2
- package/dist/scoops/cli.js +2 -0
- package/dist/scoops/cli.js.map +2 -2
- package/dist/scoops/index.js +39 -10
- package/dist/scoops/index.js.map +2 -2
- package/dist/scoops/requests.js +1 -1
- package/dist/scoops/requests.js.map +2 -2
- package/dist/types/host.d.ts +3 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/kernel/users.d.ts +53 -0
- package/dist/types/main.d.ts +4 -0
- package/dist/types/models/index.d.ts +16 -0
- package/dist/types/owner.d.ts +2 -3
- package/dist/types/scoops/cli.d.ts +1 -0
- package/dist/types/scoops/index.d.ts +5 -1
- package/dist/types/scoops/requests.d.ts +1 -1
- package/dist/types/worker.d.ts +5 -0
- package/dist/worker.js +9 -3
- package/dist/worker.js.map +2 -2
- package/package.json +2 -2
- package/packages/vfs-root/skills/agent/SKILL.md +2 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { THINKING } from "../scoops/cli.js";
|
|
2
|
+
const LEVELS = [...THINKING].join(", ");
|
|
3
|
+
const USAGE = `usage:
|
|
4
|
+
models [list] [--json] the models you can use, * marks the current one
|
|
5
|
+
models current [--json] the current model
|
|
6
|
+
models use <provider/model> [--thinking <level>] switch this agent's model, as the Settings picker does
|
|
7
|
+
|
|
8
|
+
levels: ${LEVELS}
|
|
9
|
+
In an agent's bash, models switches that cone or scoop; in a terminal, the active cone.
|
|
10
|
+
`;
|
|
11
|
+
const ok = (out) => ({ code: 0, out });
|
|
12
|
+
const fail = (out, code = 1) => ({ code, out: `models: ${out}
|
|
13
|
+
` });
|
|
14
|
+
function distance(a, b) {
|
|
15
|
+
let previous = Array.from({ length: b.length + 1 }, (_, at) => at);
|
|
16
|
+
for (let i = 1; i <= a.length; i++) {
|
|
17
|
+
const row = [i];
|
|
18
|
+
for (let j = 1; j <= b.length; j++)
|
|
19
|
+
row[j] = Math.min(
|
|
20
|
+
previous[j] + 1,
|
|
21
|
+
row[j - 1] + 1,
|
|
22
|
+
previous[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1)
|
|
23
|
+
);
|
|
24
|
+
previous = row;
|
|
25
|
+
}
|
|
26
|
+
return previous[b.length];
|
|
27
|
+
}
|
|
28
|
+
function closest(wanted, ids, count = 3) {
|
|
29
|
+
const target = wanted.toLowerCase();
|
|
30
|
+
const score = (id) => {
|
|
31
|
+
const lower = id.toLowerCase();
|
|
32
|
+
const tail = lower.slice(lower.indexOf("/") + 1);
|
|
33
|
+
const near = Math.min(distance(target, lower), distance(target, tail));
|
|
34
|
+
return lower.includes(target) || target.includes(tail) ? near - 1e3 : near;
|
|
35
|
+
};
|
|
36
|
+
return [...new Set(ids)].map((id) => ({ id, score: score(id) })).sort((a, b) => a.score - b.score || a.id.localeCompare(b.id)).slice(0, count).map((entry) => entry.id);
|
|
37
|
+
}
|
|
38
|
+
function agentOf(agents, caller) {
|
|
39
|
+
if (caller?.startsWith("cone:")) return caller.slice(5);
|
|
40
|
+
return caller ?? agents.activeCone();
|
|
41
|
+
}
|
|
42
|
+
async function conversationOf(agents, caller, context) {
|
|
43
|
+
const id = agentOf(agents, caller);
|
|
44
|
+
const found = await agents.conversation(id, context);
|
|
45
|
+
if (!found) throw new Error(`there is no agent ${id}`);
|
|
46
|
+
return found;
|
|
47
|
+
}
|
|
48
|
+
async function currentOf(conversation, context) {
|
|
49
|
+
const agent = await conversation.agent(context);
|
|
50
|
+
return {
|
|
51
|
+
id: agent.model ? `${agent.model.provider}/${agent.model.modelId}` : null,
|
|
52
|
+
thinking: agent.thinkingLevel
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function stateOf(options) {
|
|
56
|
+
return options.settings.state.value ?? { models: [], accounts: [] };
|
|
57
|
+
}
|
|
58
|
+
function account(state, choice) {
|
|
59
|
+
const providerId = choice.id.slice(0, choice.id.indexOf("/"));
|
|
60
|
+
const found = state.accounts.find((entry) => entry.id === providerId);
|
|
61
|
+
return found?.identity ? `${choice.provider} (${found.identity})` : choice.provider;
|
|
62
|
+
}
|
|
63
|
+
function rows(state, current) {
|
|
64
|
+
return state.models.map((choice) => ({
|
|
65
|
+
id: choice.id,
|
|
66
|
+
label: choice.label,
|
|
67
|
+
provider: choice.provider,
|
|
68
|
+
account: account(state, choice),
|
|
69
|
+
reasoning: choice.reasoning,
|
|
70
|
+
contextWindow: choice.contextWindow,
|
|
71
|
+
current: choice.id === current.id
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
function missing(state, id) {
|
|
75
|
+
const providerId = id.slice(0, id.indexOf("/"));
|
|
76
|
+
const connected = state.accounts.some(
|
|
77
|
+
(entry) => entry.id === providerId && entry.status === "connected"
|
|
78
|
+
);
|
|
79
|
+
return connected ? `current: ${id}, which its account no longer offers` : `current: ${id}, whose account is not connected`;
|
|
80
|
+
}
|
|
81
|
+
function list(state, current, json) {
|
|
82
|
+
const listed = rows(state, current);
|
|
83
|
+
if (json) return ok(`${JSON.stringify(listed, null, 2)}
|
|
84
|
+
`);
|
|
85
|
+
const lines = listed.map(
|
|
86
|
+
(row) => `${row.current ? "*" : " "} ${row.id} ${row.label} ${row.account}`
|
|
87
|
+
);
|
|
88
|
+
if (!listed.length) lines.push("no models: connect an account in Settings");
|
|
89
|
+
if (current.id && !listed.some((row) => row.current)) lines.push(missing(state, current.id));
|
|
90
|
+
return ok(`${lines.join("\n")}
|
|
91
|
+
`);
|
|
92
|
+
}
|
|
93
|
+
function show(state, current, json) {
|
|
94
|
+
if (!json) return ok(`${current.id ?? "none"}
|
|
95
|
+
`);
|
|
96
|
+
const found = rows(state, current).find((row) => row.current);
|
|
97
|
+
return ok(
|
|
98
|
+
`${JSON.stringify({ id: current.id, thinking: current.thinking, label: found?.label ?? null, provider: found?.provider ?? null, available: Boolean(found) }, null, 2)}
|
|
99
|
+
`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
function refuse(options, state, wanted) {
|
|
103
|
+
const at = wanted.indexOf("/");
|
|
104
|
+
const providerId = at > 0 ? wanted.slice(0, at) : "";
|
|
105
|
+
const modelId = wanted.slice(at + 1);
|
|
106
|
+
const disconnected = state.accounts.find(
|
|
107
|
+
(entry) => entry.id === providerId && entry.status !== "connected"
|
|
108
|
+
);
|
|
109
|
+
const known = options.catalog.getModels(providerId);
|
|
110
|
+
if (disconnected && (!known.length || known.some((model) => model.id === modelId)))
|
|
111
|
+
return fail(
|
|
112
|
+
`${wanted} needs the ${disconnected.provider} account; connect it in Settings, then try again`
|
|
113
|
+
);
|
|
114
|
+
const ids = [
|
|
115
|
+
...state.models.map((choice) => choice.id),
|
|
116
|
+
...options.catalog.getProviders().flatMap(
|
|
117
|
+
(provider) => options.catalog.getModels(provider.id).map((model) => `${provider.id}/${model.id}`)
|
|
118
|
+
)
|
|
119
|
+
];
|
|
120
|
+
const near = closest(wanted, ids);
|
|
121
|
+
return fail(
|
|
122
|
+
`there is no model ${wanted}${near.length ? `; the closest are ${near.join(", ")}` : ""}`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
async function use(options, argv, caller, context) {
|
|
126
|
+
const rest = [];
|
|
127
|
+
let thinking;
|
|
128
|
+
for (let at2 = 0; at2 < argv.length; at2++) {
|
|
129
|
+
const arg = argv[at2];
|
|
130
|
+
if (arg === "--thinking") {
|
|
131
|
+
thinking = argv[++at2];
|
|
132
|
+
if (thinking === void 0) return fail("--thinking needs a level", 2);
|
|
133
|
+
} else if (arg.startsWith("-")) return fail(`unknown option ${arg}`, 2);
|
|
134
|
+
else rest.push(arg);
|
|
135
|
+
}
|
|
136
|
+
if (rest.length !== 1) return { code: 2, out: USAGE };
|
|
137
|
+
if (thinking !== void 0 && !THINKING.has(thinking))
|
|
138
|
+
return fail(`--thinking must be one of ${LEVELS}`, 2);
|
|
139
|
+
const wanted = rest[0];
|
|
140
|
+
const state = stateOf(options);
|
|
141
|
+
const choice = state.models.find((entry) => entry.id === wanted);
|
|
142
|
+
if (!choice) return refuse(options, state, wanted);
|
|
143
|
+
const at = wanted.indexOf("/");
|
|
144
|
+
const change = {
|
|
145
|
+
model: { provider: wanted.slice(0, at), modelId: wanted.slice(at + 1) },
|
|
146
|
+
...thinking ? { thinkingLevel: thinking } : {}
|
|
147
|
+
};
|
|
148
|
+
const conversation = await conversationOf(options.agents, caller, context);
|
|
149
|
+
await conversation.configure(change, context);
|
|
150
|
+
const now = await currentOf(conversation, context);
|
|
151
|
+
return ok(`now using ${now.id} (${choice.label}), thinking ${now.thinking}
|
|
152
|
+
`);
|
|
153
|
+
}
|
|
154
|
+
function modelsCommand(options) {
|
|
155
|
+
return async (argv, caller, context) => {
|
|
156
|
+
try {
|
|
157
|
+
const [verb = "list", ...rest] = argv;
|
|
158
|
+
if (verb === "--help" || verb === "-h" || verb === "help") return ok(USAGE);
|
|
159
|
+
if (verb === "use") return await use(options, rest, caller, context);
|
|
160
|
+
const listing = verb === "list" || verb === "--json";
|
|
161
|
+
if (!listing && verb !== "current") return { code: 2, out: USAGE };
|
|
162
|
+
const flags = verb === "--json" ? argv : rest;
|
|
163
|
+
const unknown = flags.find((arg) => arg !== "--json");
|
|
164
|
+
if (unknown) return { code: 2, out: USAGE };
|
|
165
|
+
const json = flags.includes("--json");
|
|
166
|
+
const state = stateOf(options);
|
|
167
|
+
const current = await currentOf(
|
|
168
|
+
await conversationOf(options.agents, caller, context),
|
|
169
|
+
context
|
|
170
|
+
);
|
|
171
|
+
return listing ? list(state, current, json) : show(state, current, json);
|
|
172
|
+
} catch (error) {
|
|
173
|
+
return fail(error.message);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
export {
|
|
178
|
+
USAGE,
|
|
179
|
+
closest,
|
|
180
|
+
modelsCommand
|
|
181
|
+
};
|
|
182
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/models/index.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { Models } from '@earendil-works/pi-ai/models';\nimport type { AgentChange, Conversation } from '@earendil-works/pi-durable';\nimport type { Agents } from '../agents.ts';\nimport { THINKING } from '../scoops/cli.ts';\nimport type { AgentSettings, ModelChoice, SettingsState } from '../services.ts';\n\nexport type Answer = { code: number; out: string };\n\nconst LEVELS = [...THINKING].join(', ');\n\nexport const USAGE = `usage:\n models [list] [--json] the models you can use, * marks the current one\n models current [--json] the current model\n models use <provider/model> [--thinking <level>] switch this agent's model, as the Settings picker does\n\nlevels: ${LEVELS}\nIn an agent's bash, models switches that cone or scoop; in a terminal, the active cone.\n`;\n\nexport interface ModelsOptions {\n agents: Agents;\n settings: Pick<AgentSettings, 'state'>;\n catalog: Pick<Models, 'getProviders' | 'getModels'>;\n}\n\nconst ok = (out: string): Answer => ({ code: 0, out });\nconst fail = (out: string, code = 1): Answer => ({ code, out: `models: ${out}\\n` });\n\nfunction distance(a: string, b: string): number {\n let previous = Array.from({ length: b.length + 1 }, (_, at) => at);\n for (let i = 1; i <= a.length; i++) {\n const row = [i];\n for (let j = 1; j <= b.length; j++)\n row[j] = Math.min(\n (previous[j] as number) + 1,\n (row[j - 1] as number) + 1,\n (previous[j - 1] as number) + (a[i - 1] === b[j - 1] ? 0 : 1)\n );\n previous = row;\n }\n return previous[b.length] as number;\n}\n\nexport function closest(wanted: string, ids: readonly string[], count = 3): string[] {\n const target = wanted.toLowerCase();\n const score = (id: string) => {\n const lower = id.toLowerCase();\n const tail = lower.slice(lower.indexOf('/') + 1);\n const near = Math.min(distance(target, lower), distance(target, tail));\n return lower.includes(target) || target.includes(tail) ? near - 1000 : near;\n };\n return [...new Set(ids)]\n .map((id) => ({ id, score: score(id) }))\n .sort((a, b) => a.score - b.score || a.id.localeCompare(b.id))\n .slice(0, count)\n .map((entry) => entry.id);\n}\n\nfunction agentOf(agents: Agents, caller: string | null): string {\n if (caller?.startsWith('cone:')) return caller.slice(5);\n return caller ?? agents.activeCone();\n}\n\nasync function conversationOf(agents: Agents, caller: string | null, context: Context) {\n const id = agentOf(agents, caller);\n const found = await agents.conversation(id, context);\n if (!found) throw new Error(`there is no agent ${id}`);\n return found;\n}\n\ntype Current = { id: string | null; thinking: string };\n\nasync function currentOf(conversation: Conversation, context: Context): Promise<Current> {\n const agent = await conversation.agent(context);\n return {\n id: agent.model ? `${agent.model.provider}/${agent.model.modelId}` : null,\n thinking: agent.thinkingLevel,\n };\n}\n\nfunction stateOf(options: ModelsOptions): SettingsState {\n return options.settings.state.value ?? { models: [], accounts: [] };\n}\n\nfunction account(state: SettingsState, choice: ModelChoice): string {\n const providerId = choice.id.slice(0, choice.id.indexOf('/'));\n const found = state.accounts.find((entry) => entry.id === providerId);\n return found?.identity ? `${choice.provider} (${found.identity})` : choice.provider;\n}\n\nfunction rows(state: SettingsState, current: Current) {\n return state.models.map((choice) => ({\n id: choice.id,\n label: choice.label,\n provider: choice.provider,\n account: account(state, choice),\n reasoning: choice.reasoning,\n contextWindow: choice.contextWindow,\n current: choice.id === current.id,\n }));\n}\n\nfunction missing(state: SettingsState, id: string): string {\n const providerId = id.slice(0, id.indexOf('/'));\n const connected = state.accounts.some(\n (entry) => entry.id === providerId && entry.status === 'connected'\n );\n return connected\n ? `current: ${id}, which its account no longer offers`\n : `current: ${id}, whose account is not connected`;\n}\n\nfunction list(state: SettingsState, current: Current, json: boolean): Answer {\n const listed = rows(state, current);\n if (json) return ok(`${JSON.stringify(listed, null, 2)}\\n`);\n const lines = listed.map(\n (row) => `${row.current ? '*' : ' '} ${row.id}\\t${row.label}\\t${row.account}`\n );\n if (!listed.length) lines.push('no models: connect an account in Settings');\n if (current.id && !listed.some((row) => row.current)) lines.push(missing(state, current.id));\n return ok(`${lines.join('\\n')}\\n`);\n}\n\nfunction show(state: SettingsState, current: Current, json: boolean): Answer {\n if (!json) return ok(`${current.id ?? 'none'}\\n`);\n const found = rows(state, current).find((row) => row.current);\n return ok(\n `${JSON.stringify({ id: current.id, thinking: current.thinking, label: found?.label ?? null, provider: found?.provider ?? null, available: Boolean(found) }, null, 2)}\\n`\n );\n}\n\nfunction refuse(options: ModelsOptions, state: SettingsState, wanted: string): Answer {\n const at = wanted.indexOf('/');\n const providerId = at > 0 ? wanted.slice(0, at) : '';\n const modelId = wanted.slice(at + 1);\n const disconnected = state.accounts.find(\n (entry) => entry.id === providerId && entry.status !== 'connected'\n );\n const known = options.catalog.getModels(providerId);\n if (disconnected && (!known.length || known.some((model) => model.id === modelId)))\n return fail(\n `${wanted} needs the ${disconnected.provider} account; connect it in Settings, then try again`\n );\n const ids = [\n ...state.models.map((choice) => choice.id),\n ...options.catalog\n .getProviders()\n .flatMap((provider) =>\n options.catalog.getModels(provider.id).map((model) => `${provider.id}/${model.id}`)\n ),\n ];\n const near = closest(wanted, ids);\n return fail(\n `there is no model ${wanted}${near.length ? `; the closest are ${near.join(', ')}` : ''}`\n );\n}\n\nasync function use(\n options: ModelsOptions,\n argv: readonly string[],\n caller: string | null,\n context: Context\n): Promise<Answer> {\n const rest: string[] = [];\n let thinking: string | undefined;\n for (let at = 0; at < argv.length; at++) {\n const arg = argv[at] as string;\n if (arg === '--thinking') {\n thinking = argv[++at];\n if (thinking === undefined) return fail('--thinking needs a level', 2);\n } else if (arg.startsWith('-')) return fail(`unknown option ${arg}`, 2);\n else rest.push(arg);\n }\n if (rest.length !== 1) return { code: 2, out: USAGE };\n if (thinking !== undefined && !THINKING.has(thinking))\n return fail(`--thinking must be one of ${LEVELS}`, 2);\n const wanted = rest[0] as string;\n const state = stateOf(options);\n const choice = state.models.find((entry) => entry.id === wanted);\n if (!choice) return refuse(options, state, wanted);\n const at = wanted.indexOf('/');\n const change: AgentChange = {\n model: { provider: wanted.slice(0, at), modelId: wanted.slice(at + 1) },\n ...(thinking ? { thinkingLevel: thinking as AgentChange['thinkingLevel'] } : {}),\n };\n const conversation = await conversationOf(options.agents, caller, context);\n await conversation.configure(change, context);\n const now = await currentOf(conversation, context);\n return ok(`now using ${now.id} (${choice.label}), thinking ${now.thinking}\\n`);\n}\n\nexport function modelsCommand(options: ModelsOptions) {\n return async (argv: readonly string[], caller: string | null, context: Context) => {\n try {\n const [verb = 'list', ...rest] = argv;\n if (verb === '--help' || verb === '-h' || verb === 'help') return ok(USAGE);\n if (verb === 'use') return await use(options, rest, caller, context);\n const listing = verb === 'list' || verb === '--json';\n if (!listing && verb !== 'current') return { code: 2, out: USAGE };\n const flags = verb === '--json' ? argv : rest;\n const unknown = flags.find((arg) => arg !== '--json');\n if (unknown) return { code: 2, out: USAGE };\n const json = flags.includes('--json');\n const state = stateOf(options);\n const current = await currentOf(\n await conversationOf(options.agents, caller, context),\n context\n );\n return listing ? list(state, current, json) : show(state, current, json);\n } catch (error) {\n return fail((error as Error).message);\n }\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["at"]
|
|
7
|
+
}
|
package/dist/owner.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { connectAgent } from "./client.js";
|
|
2
|
+
import { serveAdmin } from "./kernel/users.js";
|
|
2
3
|
import { holdLock } from "./opfs-pool.js";
|
|
3
4
|
const AGENT_LOCK = "slicc-agent";
|
|
4
5
|
async function startAgent(options) {
|
|
@@ -6,16 +7,32 @@ async function startAgent(options) {
|
|
|
6
7
|
const channel = options.channel ?? (() => new MessageChannel());
|
|
7
8
|
const spawn = async () => {
|
|
8
9
|
const created = options.worker();
|
|
10
|
+
let admin;
|
|
9
11
|
try {
|
|
10
12
|
if (options.kernel) {
|
|
11
13
|
const port = await options.kernel.connect();
|
|
12
|
-
created.postMessage({ kernel: port }, [port]);
|
|
14
|
+
if (!options.kernel.users) created.postMessage({ kernel: port }, [port]);
|
|
15
|
+
else {
|
|
16
|
+
const { port1, port2 } = channel();
|
|
17
|
+
admin = port1;
|
|
18
|
+
serveAdmin(port1, options.kernel);
|
|
19
|
+
created.postMessage({ kernel: port, admin: port2 }, [port, port2]);
|
|
20
|
+
}
|
|
13
21
|
}
|
|
14
22
|
} catch (error) {
|
|
23
|
+
admin?.close?.();
|
|
15
24
|
created.terminate();
|
|
16
25
|
throw error;
|
|
17
26
|
}
|
|
18
|
-
return created;
|
|
27
|
+
if (!admin) return created;
|
|
28
|
+
const served = admin;
|
|
29
|
+
return {
|
|
30
|
+
postMessage: (message, transfer) => created.postMessage(message, transfer),
|
|
31
|
+
terminate() {
|
|
32
|
+
served.close?.();
|
|
33
|
+
created.terminate();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
19
36
|
};
|
|
20
37
|
let worker = Promise.resolve().then(spawn);
|
|
21
38
|
try {
|
package/dist/owner.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/owner.ts"],
|
|
4
|
-
"sourcesContent": ["import { type AgentConnection, connectAgent } from './client.ts';\nimport { holdLock } from './opfs-pool.ts';\nimport type { PortEndpoint } from './wire.ts';\n\nexport const AGENT_LOCK = 'slicc-agent';\n\nexport interface AgentWorker {\n postMessage(message: unknown, transfer: Transferable[]): void;\n terminate(): void;\n}\n\nexport interface PortOptions {\n readOnly?: boolean;\n}\n\nexport interface AgentOwner {\n connect(options?: PortOptions): Promise<AgentConnection>;\n port(options?: PortOptions): Promise<PortEndpoint & Transferable>;\n restart(): Promise<void>;\n release(): Promise<void>;\n}\n\nexport
|
|
5
|
-
"mappings": "AAAA,SAA+B,oBAAoB;AACnD,SAAS,gBAAgB;AAGlB,MAAM,aAAa;
|
|
4
|
+
"sourcesContent": ["import { type AgentConnection, connectAgent } from './client.ts';\nimport { type KernelSource, serveAdmin } from './kernel/users.ts';\nimport { holdLock } from './opfs-pool.ts';\nimport type { PortEndpoint } from './wire.ts';\n\nexport const AGENT_LOCK = 'slicc-agent';\n\nexport interface AgentWorker {\n postMessage(message: unknown, transfer: Transferable[]): void;\n terminate(): void;\n}\n\nexport interface PortOptions {\n readOnly?: boolean;\n}\n\nexport interface AgentOwner {\n connect(options?: PortOptions): Promise<AgentConnection>;\n port(options?: PortOptions): Promise<PortEndpoint & Transferable>;\n restart(): Promise<void>;\n release(): Promise<void>;\n}\n\nexport type { KernelSource } from './kernel/users.ts';\n\nexport interface OwnerOptions {\n worker: () => AgentWorker;\n kernel?: KernelSource;\n locks?: LockManager;\n held?: boolean;\n channel?: () => { port1: PortEndpoint & Transferable; port2: Transferable };\n}\n\nexport async function startAgent(options: OwnerOptions): Promise<AgentOwner> {\n const release = options.held\n ? () => undefined\n : await holdLock(options.locks ?? navigator.locks, AGENT_LOCK);\n const channel = options.channel ?? (() => new MessageChannel());\n const spawn = async (): Promise<AgentWorker> => {\n const created = options.worker();\n let admin: (PortEndpoint & Transferable) | undefined;\n try {\n if (options.kernel) {\n const port = await options.kernel.connect();\n if (!options.kernel.users) created.postMessage({ kernel: port }, [port]);\n else {\n const { port1, port2 } = channel();\n admin = port1;\n serveAdmin(port1, options.kernel);\n created.postMessage({ kernel: port, admin: port2 }, [port, port2]);\n }\n }\n } catch (error) {\n admin?.close?.();\n created.terminate();\n throw error;\n }\n if (!admin) return created;\n const served = admin;\n return {\n postMessage: (message, transfer) => created.postMessage(message, transfer),\n terminate() {\n served.close?.();\n created.terminate();\n },\n };\n };\n let worker: Promise<AgentWorker | undefined> = Promise.resolve().then(spawn);\n try {\n await worker;\n } catch (error) {\n release();\n throw error;\n }\n const open = async (portOptions: PortOptions = {}): Promise<PortEndpoint & Transferable> => {\n const ready = await worker;\n if (!ready) throw new Error('the agent was released');\n const { port1, port2 } = channel();\n const readOnly = portOptions.readOnly === true ? { readOnly: true } : {};\n ready.postMessage({ connect: port2, ...readOnly }, [port2]);\n return port1;\n };\n return {\n async connect(portOptions) {\n return connectAgent(await open(portOptions));\n },\n port: open,\n restart() {\n worker = worker\n .catch(() => undefined)\n .then((old) => {\n old?.terminate();\n return spawn();\n });\n return worker.then(() => undefined);\n },\n async release() {\n const previous = worker;\n worker = Promise.resolve(undefined);\n try {\n (await previous.catch(() => undefined))?.terminate();\n } finally {\n release();\n }\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAA+B,oBAAoB;AACnD,SAA4B,kBAAkB;AAC9C,SAAS,gBAAgB;AAGlB,MAAM,aAAa;AA4B1B,eAAsB,WAAW,SAA4C;AAC3E,QAAM,UAAU,QAAQ,OACpB,MAAM,SACN,MAAM,SAAS,QAAQ,SAAS,UAAU,OAAO,UAAU;AAC/D,QAAM,UAAU,QAAQ,YAAY,MAAM,IAAI,eAAe;AAC7D,QAAM,QAAQ,YAAkC;AAC9C,UAAM,UAAU,QAAQ,OAAO;AAC/B,QAAI;AACJ,QAAI;AACF,UAAI,QAAQ,QAAQ;AAClB,cAAM,OAAO,MAAM,QAAQ,OAAO,QAAQ;AAC1C,YAAI,CAAC,QAAQ,OAAO,MAAO,SAAQ,YAAY,EAAE,QAAQ,KAAK,GAAG,CAAC,IAAI,CAAC;AAAA,aAClE;AACH,gBAAM,EAAE,OAAO,MAAM,IAAI,QAAQ;AACjC,kBAAQ;AACR,qBAAW,OAAO,QAAQ,MAAM;AAChC,kBAAQ,YAAY,EAAE,QAAQ,MAAM,OAAO,MAAM,GAAG,CAAC,MAAM,KAAK,CAAC;AAAA,QACnE;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO,QAAQ;AACf,cAAQ,UAAU;AAClB,YAAM;AAAA,IACR;AACA,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,SAAS;AACf,WAAO;AAAA,MACL,aAAa,CAAC,SAAS,aAAa,QAAQ,YAAY,SAAS,QAAQ;AAAA,MACzE,YAAY;AACV,eAAO,QAAQ;AACf,gBAAQ,UAAU;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AACA,MAAI,SAA2C,QAAQ,QAAQ,EAAE,KAAK,KAAK;AAC3E,MAAI;AACF,UAAM;AAAA,EACR,SAAS,OAAO;AACd,YAAQ;AACR,UAAM;AAAA,EACR;AACA,QAAM,OAAO,OAAO,cAA2B,CAAC,MAA4C;AAC1F,UAAM,QAAQ,MAAM;AACpB,QAAI,CAAC,MAAO,OAAM,IAAI,MAAM,wBAAwB;AACpD,UAAM,EAAE,OAAO,MAAM,IAAI,QAAQ;AACjC,UAAM,WAAW,YAAY,aAAa,OAAO,EAAE,UAAU,KAAK,IAAI,CAAC;AACvE,UAAM,YAAY,EAAE,SAAS,OAAO,GAAG,SAAS,GAAG,CAAC,KAAK,CAAC;AAC1D,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,MAAM,QAAQ,aAAa;AACzB,aAAO,aAAa,MAAM,KAAK,WAAW,CAAC;AAAA,IAC7C;AAAA,IACA,MAAM;AAAA,IACN,UAAU;AACR,eAAS,OACN,MAAM,MAAM,MAAS,EACrB,KAAK,CAAC,QAAQ;AACb,aAAK,UAAU;AACf,eAAO,MAAM;AAAA,MACf,CAAC;AACH,aAAO,OAAO,KAAK,MAAM,MAAS;AAAA,IACpC;AAAA,IACA,MAAM,UAAU;AACd,YAAM,WAAW;AACjB,eAAS,QAAQ,QAAQ,MAAS;AAClC,UAAI;AACF,SAAC,MAAM,SAAS,MAAM,MAAM,MAAS,IAAI,UAAU;AAAA,MACrD,UAAE;AACA,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/scoops/cli.js
CHANGED
|
@@ -349,6 +349,8 @@ async function dispatch(deps, request, who, context) {
|
|
|
349
349
|
return deps.gelatiere ? deps.gelatiere(request.argv, who.id, context) : fail("the gelatiere is not available in this agent");
|
|
350
350
|
if (request.as === "freezer")
|
|
351
351
|
return deps.freezer ? deps.freezer(request.argv, who.id, context) : fail("the freezer is not available in this agent");
|
|
352
|
+
if (request.as === "models")
|
|
353
|
+
return deps.models ? deps.models(request.argv, who.id, context) : fail("models is not available in this agent");
|
|
352
354
|
const first = request.argv[0] ?? "";
|
|
353
355
|
const verb = VERBS[first];
|
|
354
356
|
if (verb) return verb(deps, request, who, context);
|
package/dist/scoops/cli.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/scoops/cli.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { Harness } from '@earendil-works/pi-durable';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport type { Agents, AgentsState } from '../agents.ts';\nimport { resolve } from '../kernel/paths.ts';\nimport { findRole, type Roles } from '../roles/roles.ts';\nimport type { Request, Runner } from './requests.ts';\nimport { type Answer, findScoop, modelOf, SCOOPS_ROOT, type Scoops } from './service.ts';\nimport { cancelSync, detachSync, runSync, type SyncState } from './sync.ts';\n\nexport const DEFAULT_WAIT_S = 30;\nexport const MAX_DEPTH = 3;\nexport const RUN_DIR = '/var/lib/slicc/agent/scoops';\n\nexport const THINKING = new Set(['off', 'minimal', 'low', 'medium', 'high', 'xhigh']);\nconst EFFORT: Record<string, string> = { low: 'low', medium: 'medium', high: 'high', max: 'xhigh' };\n\nexport const USAGE = `usage:\n agent [options] (--prompt <text> | --file <path> | -)... run a scoop, wait, print its answer\n agent --async [options] (--prompt <text> | --file <path> | -)... start a scoop, print its handle\n agent <cwd> <allowed-commands> <prompt> the same as a synchronous run, in v6's form\n agent list [--agents] | status <handle> | rename <handle> <name>\n agent send <handle> [--follow-up] (<message> | --file <path> | -)\n agent send parent <note> from a scoop: a progress note to its cone\n agent wait <handle>... [--timeout <seconds>] [--notify]\n agent stop <handle>\n\noptions:\n --name <name> --agent <role> --model <provider/model> --thinking <level> | --effort <low|medium|high|max>\n --tools <a,b> --read-only <path,path> --system-prompt <text> | --system-prompt-file <path>\n --background-after <seconds> --persist-session | --no-persist-session\n\nA synchronous run removes the scoop's folder afterwards. Its transcript is archived in\n/tmp/agent-sessions/<handle>.md, in /home/sessions/<handle>.md with --persist-session, or nowhere\nwith --no-persist-session. subagent is the same command: subagent spawn = agent --async.\n`;\n\nexport interface CliOptions {\n env: ExecutionEnv;\n harness: Harness;\n agents: Agents;\n scoops: Scoops;\n roles: () => Promise<Roles>;\n alive?: (pid: number) => Promise<boolean>;\n now?: () => number;\n sprinkle?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n memory?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n gelatiere?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n freezer?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n}\n\nexport type Deps = CliOptions & { now: () => number; sync: SyncState };\n\nexport interface Caller {\n id: string | null;\n cone: string;\n fromAgent: boolean;\n scoop: string | null;\n depth: number;\n}\n\nexport type Flags = { values: Map<string, string[]>; switches: Set<string>; rest: string[] };\n\nexport const ok = (out: string): Answer => ({ code: 0, out });\nexport const fail = (out: string, code = 1): Answer => ({ code, out: `agent: ${out}\\n` });\n\nexport function isAnswer(value: unknown): value is Answer {\n return typeof value === 'object' && value !== null && 'code' in value && 'out' in value;\n}\n\nexport function flags(argv: readonly string[], withValue: readonly string[]): Flags {\n const values = new Map<string, string[]>();\n const switches = new Set<string>();\n const rest: string[] = [];\n for (let at = 0; at < argv.length; at++) {\n const arg = argv[at] as string;\n if (withValue.includes(arg)) {\n const value = argv[at + 1];\n if (value === undefined) throw new Error(`${arg} needs a value`);\n values.set(arg, [...(values.get(arg) ?? []), value]);\n at++;\n } else if (arg.startsWith('--')) switches.add(arg);\n else rest.push(arg);\n }\n return { values, switches, rest };\n}\n\nexport function last(parsed: Flags, flag: string): string | undefined {\n return parsed.values.get(flag)?.at(-1);\n}\n\nexport function callerOf(agents: Agents, request: Request): Caller {\n const state = agents.state();\n if (request.caller.startsWith('cone:') && state.cones[request.caller.slice(5)]) {\n const cone = request.caller.slice(5);\n return { id: `cone:${cone}`, cone, fromAgent: true, scoop: null, depth: 0 };\n }\n const record = request.caller.startsWith('scoop:') ? state.scoops[request.caller] : undefined;\n if (record)\n return {\n id: request.caller,\n cone: record.cone,\n fromAgent: true,\n scoop: request.caller,\n depth: record.depth,\n };\n return { id: null, cone: agents.activeCone(), fromAgent: false, scoop: null, depth: 0 };\n}\n\nexport async function readText(\n deps: Deps,\n value: string,\n request: Request,\n context: Context\n): Promise<string> {\n const read = await deps.env.readTextFile(resolve(request.cwd, value), context);\n if (!read.ok) throw new Error(`can't read ${value}: ${read.error.message}`);\n return read.value;\n}\n\nexport async function prompts(\n deps: Deps,\n argv: readonly string[],\n request: Request,\n context: Context\n) {\n const out: string[] = [];\n for (let at = 0; at < argv.length; at++) {\n const arg = argv[at];\n if (arg === '--prompt') out.push(argv[++at] ?? '');\n else if (arg === '--file') out.push(await readText(deps, argv[++at] ?? '', request, context));\n else if (arg === '-') out.push(request.stdin);\n }\n return out.filter((prompt) => prompt.trim());\n}\n\nexport type Choice = {\n model?: { provider: string; modelId: string };\n thinking?: string;\n tools?: string[];\n};\n\nfunction toolList(listed: string | undefined): string[] | undefined {\n if (listed === undefined || listed === 'auto' || listed === 'full') return undefined;\n return listed\n .split(',')\n .map((tool) => tool.trim())\n .filter(Boolean);\n}\n\nexport function choices(parsed: Flags): Choice | Answer {\n const provider = last(parsed, '--provider');\n const modelText = last(parsed, '--model');\n const model = modelText\n ? provider\n ? { provider, modelId: modelText }\n : modelOf(modelText)\n : undefined;\n if (modelText && !model)\n return fail('--model needs provider/model, or --provider with --model', 2);\n const effort = last(parsed, '--effort');\n if (effort && !EFFORT[effort]) return fail('--effort must be low, medium, high or max', 2);\n const thinking = last(parsed, '--thinking') ?? (effort ? EFFORT[effort] : undefined);\n if (thinking && !THINKING.has(thinking))\n return fail(`--thinking must be one of ${[...THINKING].join(', ')}`, 2);\n if (last(parsed, '--tools') === 'output')\n return fail('--tools output needs --schema-b64, which is not supported in SLICC yet', 2);\n const tools = toolList(last(parsed, '--tools'));\n return {\n ...(model ? { model } : {}),\n ...(thinking ? { thinking } : {}),\n ...(tools ? { tools } : {}),\n };\n}\n\nexport async function role(deps: Deps, parsed: Flags) {\n const roles = await deps.roles();\n const name = last(parsed, '--agent');\n const found = name ? findRole(roles.roles, name) : undefined;\n if (name && !found)\n return {\n roles,\n error: fail(`there is no agent role ${name}; \\`agent list --agents\\` shows them`),\n };\n return { roles, role: found };\n}\n\nfunction handle(deps: Deps, who: Caller, name: string | undefined) {\n return name ? findScoop(deps.agents.state(), name, who.fromAgent ? who.cone : null) : undefined;\n}\n\nconst ASYNC_VALUES = [\n '--name',\n '--agent',\n '--provider',\n '--model',\n '--thinking',\n '--effort',\n '--tools',\n '--prompt',\n '--file',\n];\nconst ASYNC_SWITCHES = new Set(['--async', '--no-extensions', '--no-skills', '--no-context-files']);\nconst UNSUPPORTED = new Set([\n '--no-prompt-templates',\n '--session',\n '--resume',\n '--image',\n '--no-escalate',\n '--minimal',\n '--usage',\n '--schema-b64',\n '--cwd',\n]);\n\nexport function unsupported(argv: readonly string[]): Answer | undefined {\n const found = argv.find((arg) => UNSUPPORTED.has(arg) || arg.startsWith('--image='));\n return found ? fail(`${found} is not supported in SLICC yet`, 2) : undefined;\n}\n\nasync function spawnAsync(\n deps: Deps,\n request: Request,\n who: Caller,\n argv: readonly string[],\n context: Context\n) {\n if (who.scoop) return fail('a scoop cannot start async scoops; run agent without --async');\n const refused = unsupported(argv);\n if (refused) return refused;\n const parsed = flags(argv, ASYNC_VALUES);\n const unknown = [...parsed.switches].find((flag) => !ASYNC_SWITCHES.has(flag));\n if (unknown) return fail(`unknown option ${unknown}`, 2);\n const given = await prompts(deps, argv, request, context);\n if (!given.length) return fail('--async needs at least one --prompt, --file or -', 2);\n const chosen = choices(parsed);\n if (isAnswer(chosen)) return chosen;\n const found = await role(deps, parsed);\n if (found.error) return found.error;\n return deps.scoops.spawn(\n {\n cone: who.cone,\n kind: 'async',\n name: last(parsed, '--name') ?? found.role?.name ?? 'scoop',\n ...(found.role ? { role: found.role } : {}),\n ...(chosen.model ? { model: chosen.model } : {}),\n ...(chosen.thinking ? { thinking: chosen.thinking as never } : {}),\n ...(chosen.tools ? { tools: chosen.tools } : {}),\n prompts: given,\n origin: request.cwd,\n fromAgent: who.fromAgent,\n request: request.id,\n limits: found.roles.limits,\n },\n context\n );\n}\n\nasync function listAgents(deps: Deps): Promise<Answer> {\n const roles = await deps.roles();\n const lines = roles.roles.map(\n (entry) =>\n `${entry.name}\\t${entry.source}\\t${entry.description}${entry.aliases.length ? ` (also ${entry.aliases.join(', ')})` : ''}`\n );\n return ok(\n `${[\n ...lines,\n '',\n 'Agent files are read from the built-in roles, installed packages (pi-subagents.agents) and ~/.pi/agent/agents.',\n \"A project's .pi/agents folder is read only once the folder is trusted, which SLICC doesn't support yet.\",\n ...roles.warnings.map((warning) => `warning: ${warning}`),\n ].join('\\n')}\\n`\n );\n}\n\nasync function list(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n if (request.argv.includes('--agents')) return listAgents(deps);\n const rows = await deps.scoops.list(who.cone, context);\n if (!rows.length) return ok('no scoops\\n');\n return ok(\n `${rows.map((row) => `${row.folder}\\t${row.name}\\t${row.role ?? '-'}\\t${row.busy ? 'working' : 'idle'}`).join('\\n')}\\n`\n );\n}\n\nasync function status(\n deps: Deps,\n request: Request,\n who: Caller,\n context: Context\n): Promise<Answer> {\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n const [, record] = found;\n const busy = await deps.scoops.busy(record.conversation, context);\n return ok(\n `${[\n `handle: ${record.folder}`,\n `name: ${record.name}`,\n `role: ${record.role ?? '-'}`,\n `kind: ${record.kind}`,\n `state: ${busy ? 'working' : 'idle'}`,\n `folder: ${SCOOPS_ROOT}/${record.folder}`,\n `reports: ${SCOOPS_ROOT}/${record.folder}/reports`,\n ].join('\\n')}\\n`\n );\n}\n\nasync function message(\n deps: Deps,\n parsed: Flags,\n request: Request,\n context: Context\n): Promise<string> {\n const file = last(parsed, '--file');\n if (file) return readText(deps, file, request, context);\n return parsed.rest.includes('-') ? request.stdin : parsed.rest.join(' ');\n}\n\nasync function send(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n const parsed = flags(request.argv.slice(2), ['--file']);\n const unknown = [...parsed.switches].find((flag) => flag !== '--follow-up');\n if (unknown) return fail(`unknown option ${unknown}`, 2);\n const text = await message(deps, parsed, request, context);\n if (!text.trim()) return fail('send needs a message, --file or -', 2);\n if (request.argv[1] === 'parent') {\n if (!who.scoop) return fail('only a scoop has a parent to send to');\n return deps.scoops.note(who.scoop, text, context);\n }\n if (who.scoop) return fail('a scoop can only send to its parent');\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n const followUp = parsed.switches.has('--follow-up');\n return deps.scoops.feed(\n found[0],\n text,\n { fromAgent: who.fromAgent, request: request.id, followUp, target: who.id },\n context\n );\n}\n\nasync function latest(deps: Deps, folder: string, context: Context): Promise<string> {\n const dir = `${SCOOPS_ROOT}/${folder}/reports`;\n const listed = await deps.env.listDir(dir, context);\n if (!listed.ok || !listed.value.length) return '(no answer yet)';\n const newest = [...listed.value].sort(\n (a, b) => Number.parseInt(b.name, 10) - Number.parseInt(a.name, 10)\n )[0];\n const read = await deps.env.readTextFile(`${dir}/${newest?.name}`, context);\n return read.ok ? read.value.trimEnd() : '(no answer yet)';\n}\n\nfunction waitTargets(deps: Deps, who: Caller, rest: readonly string[]): string[] | Answer {\n if (!rest.length) return fail('wait needs at least one handle', 2);\n const missing = rest.filter((name) => !handle(deps, who, name));\n if (missing.length)\n return fail(missing.map((name) => noScoop(deps.agents.state(), name)).join('; '));\n return rest.map((name) => (handle(deps, who, name) as [string, unknown])[0]);\n}\n\nasync function block(\n deps: Deps,\n ids: string[],\n seconds: number,\n context: Context\n): Promise<Answer> {\n const deadline = deps.now() + seconds * 1000;\n let open = await deps.scoops.working(ids, context);\n while (open.length && deps.now() < deadline) {\n await new Promise((done) => setTimeout(done, 200));\n open = await deps.scoops.working(ids, context);\n }\n const state = deps.agents.state();\n const sections: string[] = [];\n for (const id of ids) {\n const record = state.scoops[id];\n if (record)\n sections.push(\n `## ${record.folder}${open.includes(id) ? ' (still working)' : ''}\\n${await latest(deps, record.folder, context)}`\n );\n }\n const body = `${sections.join('\\n\\n')}\\n`;\n if (!open.length) return ok(body);\n const still = open.map((id) => state.scoops[id]?.folder).join(', ');\n return { code: 1, out: `${body}agent: timed out after ${seconds}s; still working: ${still}\\n` };\n}\n\nasync function wait(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n const parsed = flags(request.argv.slice(1), ['--timeout']);\n const unknown = [...parsed.switches].find((flag) => flag !== '--notify');\n if (unknown) return fail(`unknown option ${unknown}`, 2);\n const seconds = Number(last(parsed, '--timeout') ?? DEFAULT_WAIT_S);\n if (!Number.isInteger(seconds) || seconds <= 0)\n return fail('--timeout must be a positive whole number of seconds', 2);\n const ids = waitTargets(deps, who, parsed.rest);\n if (isAnswer(ids)) return ids;\n if (!parsed.switches.has('--notify')) return block(deps, ids, seconds, context);\n if (!who.fromAgent || who.scoop)\n return fail('wait --notify is for a cone; a terminal waits with agent wait');\n await deps.scoops.notifyWhenDone(who.cone, ids, deps.now() + seconds * 1000, context);\n return ok(`you'll get one scoop-wait lick when ${ids.length > 1 ? 'they are' : 'it is'} done\\n`);\n}\n\nasync function stop(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n if (who.scoop) return fail('a scoop cannot stop scoops');\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n return deps.scoops.stop(found[0], who.fromAgent, context);\n}\n\nasync function rename(\n deps: Deps,\n request: Request,\n who: Caller,\n context: Context\n): Promise<Answer> {\n if (who.scoop) return fail('a scoop cannot rename scoops');\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n return deps.scoops.rename(found[0], request.argv.slice(2).join(' '), context);\n}\n\ntype Verb = (deps: Deps, request: Request, who: Caller, context: Context) => Promise<Answer>;\n\nconst help: Verb = async () => ok(USAGE);\n\nconst VERBS: Record<string, Verb> = {\n list,\n status,\n send,\n wait,\n stop,\n rename,\n help,\n '--help': help,\n '-h': help,\n __cancel: (deps, request, _who, context) => cancelSync(deps, request.argv[1] ?? '', context),\n __detach: (deps, request, _who, context) => detachSync(deps, request.argv[1] ?? '', context),\n};\n\nexport function noScoop(state: Readonly<AgentsState>, name: string): string {\n const id = name.startsWith('scoop:') ? name : `scoop:${name}`;\n const record =\n state.scoops[id]?.frozen !== undefined\n ? state.scoops[id]\n : Object.values(state.scoops).find(\n (candidate) => candidate.frozen && candidate.name === name\n );\n const frozen = record?.frozen ? state.frozen?.[record.frozen] : undefined;\n if (frozen) return `scoop ${name} is frozen with cone ${frozen.name}; thaw the cone first`;\n return `there is no scoop ${name}`.trim();\n}\n\nasync function dispatch(\n deps: Deps,\n request: Request,\n who: Caller,\n context: Context\n): Promise<Answer> {\n if (request.as === 'sprinkle')\n return deps.sprinkle\n ? deps.sprinkle(request.argv, who.id, context)\n : fail('sprinkles are not available in this agent');\n if (request.as === 'memory')\n return deps.memory\n ? deps.memory(request.argv, who.id, context)\n : fail('memory is not available in this agent');\n if (request.as === 'gelatiere')\n return deps.gelatiere\n ? deps.gelatiere(request.argv, who.id, context)\n : fail('the gelatiere is not available in this agent');\n if (request.as === 'freezer')\n return deps.freezer\n ? deps.freezer(request.argv, who.id, context)\n : fail('the freezer is not available in this agent');\n const first = request.argv[0] ?? '';\n const verb = VERBS[first];\n if (verb) return verb(deps, request, who, context);\n if (request.as === 'subagent') {\n if (first === 'spawn') return spawnAsync(deps, request, who, request.argv.slice(1), context);\n return { code: 2, out: USAGE };\n }\n if (!request.argv.length) return { code: 2, out: USAGE };\n if (request.argv.includes('--async'))\n return spawnAsync(deps, request, who, request.argv, context);\n return runSync(deps, request, who, context);\n}\n\nconst BLOCKING = new Set([\n 'wait',\n 'list',\n 'status',\n 'help',\n '--help',\n '-h',\n '__cancel',\n '__detach',\n]);\n\nexport function createCli(options: CliOptions): Runner {\n const deps: Deps = { ...options, now: options.now ?? Date.now, sync: { pending: new Map() } };\n return {\n blocking(request) {\n const first = request.argv[0] ?? '';\n if (BLOCKING.has(first)) return true;\n return request.as === 'agent' && !VERBS[first] && !request.argv.includes('--async');\n },\n async run(request, context) {\n try {\n return await dispatch(deps, request, callerOf(options.agents, request), context);\n } catch (error) {\n return fail((error as Error).message);\n }\n },\n };\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { Harness } from '@earendil-works/pi-durable';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport type { Agents, AgentsState } from '../agents.ts';\nimport { resolve } from '../kernel/paths.ts';\nimport { findRole, type Roles } from '../roles/roles.ts';\nimport type { Request, Runner } from './requests.ts';\nimport { type Answer, findScoop, modelOf, SCOOPS_ROOT, type Scoops } from './service.ts';\nimport { cancelSync, detachSync, runSync, type SyncState } from './sync.ts';\n\nexport const DEFAULT_WAIT_S = 30;\nexport const MAX_DEPTH = 3;\nexport const RUN_DIR = '/var/lib/slicc/agent/scoops';\n\nexport const THINKING = new Set(['off', 'minimal', 'low', 'medium', 'high', 'xhigh']);\nconst EFFORT: Record<string, string> = { low: 'low', medium: 'medium', high: 'high', max: 'xhigh' };\n\nexport const USAGE = `usage:\n agent [options] (--prompt <text> | --file <path> | -)... run a scoop, wait, print its answer\n agent --async [options] (--prompt <text> | --file <path> | -)... start a scoop, print its handle\n agent <cwd> <allowed-commands> <prompt> the same as a synchronous run, in v6's form\n agent list [--agents] | status <handle> | rename <handle> <name>\n agent send <handle> [--follow-up] (<message> | --file <path> | -)\n agent send parent <note> from a scoop: a progress note to its cone\n agent wait <handle>... [--timeout <seconds>] [--notify]\n agent stop <handle>\n\noptions:\n --name <name> --agent <role> --model <provider/model> --thinking <level> | --effort <low|medium|high|max>\n --tools <a,b> --read-only <path,path> --system-prompt <text> | --system-prompt-file <path>\n --background-after <seconds> --persist-session | --no-persist-session\n\nA synchronous run removes the scoop's folder afterwards. Its transcript is archived in\n/tmp/agent-sessions/<handle>.md, in /home/sessions/<handle>.md with --persist-session, or nowhere\nwith --no-persist-session. subagent is the same command: subagent spawn = agent --async.\n`;\n\nexport interface CliOptions {\n env: ExecutionEnv;\n harness: Harness;\n agents: Agents;\n scoops: Scoops;\n roles: () => Promise<Roles>;\n alive?: (pid: number) => Promise<boolean>;\n now?: () => number;\n sprinkle?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n memory?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n gelatiere?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n freezer?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n models?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n}\n\nexport type Deps = CliOptions & { now: () => number; sync: SyncState };\n\nexport interface Caller {\n id: string | null;\n cone: string;\n fromAgent: boolean;\n scoop: string | null;\n depth: number;\n}\n\nexport type Flags = { values: Map<string, string[]>; switches: Set<string>; rest: string[] };\n\nexport const ok = (out: string): Answer => ({ code: 0, out });\nexport const fail = (out: string, code = 1): Answer => ({ code, out: `agent: ${out}\\n` });\n\nexport function isAnswer(value: unknown): value is Answer {\n return typeof value === 'object' && value !== null && 'code' in value && 'out' in value;\n}\n\nexport function flags(argv: readonly string[], withValue: readonly string[]): Flags {\n const values = new Map<string, string[]>();\n const switches = new Set<string>();\n const rest: string[] = [];\n for (let at = 0; at < argv.length; at++) {\n const arg = argv[at] as string;\n if (withValue.includes(arg)) {\n const value = argv[at + 1];\n if (value === undefined) throw new Error(`${arg} needs a value`);\n values.set(arg, [...(values.get(arg) ?? []), value]);\n at++;\n } else if (arg.startsWith('--')) switches.add(arg);\n else rest.push(arg);\n }\n return { values, switches, rest };\n}\n\nexport function last(parsed: Flags, flag: string): string | undefined {\n return parsed.values.get(flag)?.at(-1);\n}\n\nexport function callerOf(agents: Agents, request: Request): Caller {\n const state = agents.state();\n if (request.caller.startsWith('cone:') && state.cones[request.caller.slice(5)]) {\n const cone = request.caller.slice(5);\n return { id: `cone:${cone}`, cone, fromAgent: true, scoop: null, depth: 0 };\n }\n const record = request.caller.startsWith('scoop:') ? state.scoops[request.caller] : undefined;\n if (record)\n return {\n id: request.caller,\n cone: record.cone,\n fromAgent: true,\n scoop: request.caller,\n depth: record.depth,\n };\n return { id: null, cone: agents.activeCone(), fromAgent: false, scoop: null, depth: 0 };\n}\n\nexport async function readText(\n deps: Deps,\n value: string,\n request: Request,\n context: Context\n): Promise<string> {\n const read = await deps.env.readTextFile(resolve(request.cwd, value), context);\n if (!read.ok) throw new Error(`can't read ${value}: ${read.error.message}`);\n return read.value;\n}\n\nexport async function prompts(\n deps: Deps,\n argv: readonly string[],\n request: Request,\n context: Context\n) {\n const out: string[] = [];\n for (let at = 0; at < argv.length; at++) {\n const arg = argv[at];\n if (arg === '--prompt') out.push(argv[++at] ?? '');\n else if (arg === '--file') out.push(await readText(deps, argv[++at] ?? '', request, context));\n else if (arg === '-') out.push(request.stdin);\n }\n return out.filter((prompt) => prompt.trim());\n}\n\nexport type Choice = {\n model?: { provider: string; modelId: string };\n thinking?: string;\n tools?: string[];\n};\n\nfunction toolList(listed: string | undefined): string[] | undefined {\n if (listed === undefined || listed === 'auto' || listed === 'full') return undefined;\n return listed\n .split(',')\n .map((tool) => tool.trim())\n .filter(Boolean);\n}\n\nexport function choices(parsed: Flags): Choice | Answer {\n const provider = last(parsed, '--provider');\n const modelText = last(parsed, '--model');\n const model = modelText\n ? provider\n ? { provider, modelId: modelText }\n : modelOf(modelText)\n : undefined;\n if (modelText && !model)\n return fail('--model needs provider/model, or --provider with --model', 2);\n const effort = last(parsed, '--effort');\n if (effort && !EFFORT[effort]) return fail('--effort must be low, medium, high or max', 2);\n const thinking = last(parsed, '--thinking') ?? (effort ? EFFORT[effort] : undefined);\n if (thinking && !THINKING.has(thinking))\n return fail(`--thinking must be one of ${[...THINKING].join(', ')}`, 2);\n if (last(parsed, '--tools') === 'output')\n return fail('--tools output needs --schema-b64, which is not supported in SLICC yet', 2);\n const tools = toolList(last(parsed, '--tools'));\n return {\n ...(model ? { model } : {}),\n ...(thinking ? { thinking } : {}),\n ...(tools ? { tools } : {}),\n };\n}\n\nexport async function role(deps: Deps, parsed: Flags) {\n const roles = await deps.roles();\n const name = last(parsed, '--agent');\n const found = name ? findRole(roles.roles, name) : undefined;\n if (name && !found)\n return {\n roles,\n error: fail(`there is no agent role ${name}; \\`agent list --agents\\` shows them`),\n };\n return { roles, role: found };\n}\n\nfunction handle(deps: Deps, who: Caller, name: string | undefined) {\n return name ? findScoop(deps.agents.state(), name, who.fromAgent ? who.cone : null) : undefined;\n}\n\nconst ASYNC_VALUES = [\n '--name',\n '--agent',\n '--provider',\n '--model',\n '--thinking',\n '--effort',\n '--tools',\n '--prompt',\n '--file',\n];\nconst ASYNC_SWITCHES = new Set(['--async', '--no-extensions', '--no-skills', '--no-context-files']);\nconst UNSUPPORTED = new Set([\n '--no-prompt-templates',\n '--session',\n '--resume',\n '--image',\n '--no-escalate',\n '--minimal',\n '--usage',\n '--schema-b64',\n '--cwd',\n]);\n\nexport function unsupported(argv: readonly string[]): Answer | undefined {\n const found = argv.find((arg) => UNSUPPORTED.has(arg) || arg.startsWith('--image='));\n return found ? fail(`${found} is not supported in SLICC yet`, 2) : undefined;\n}\n\nasync function spawnAsync(\n deps: Deps,\n request: Request,\n who: Caller,\n argv: readonly string[],\n context: Context\n) {\n if (who.scoop) return fail('a scoop cannot start async scoops; run agent without --async');\n const refused = unsupported(argv);\n if (refused) return refused;\n const parsed = flags(argv, ASYNC_VALUES);\n const unknown = [...parsed.switches].find((flag) => !ASYNC_SWITCHES.has(flag));\n if (unknown) return fail(`unknown option ${unknown}`, 2);\n const given = await prompts(deps, argv, request, context);\n if (!given.length) return fail('--async needs at least one --prompt, --file or -', 2);\n const chosen = choices(parsed);\n if (isAnswer(chosen)) return chosen;\n const found = await role(deps, parsed);\n if (found.error) return found.error;\n return deps.scoops.spawn(\n {\n cone: who.cone,\n kind: 'async',\n name: last(parsed, '--name') ?? found.role?.name ?? 'scoop',\n ...(found.role ? { role: found.role } : {}),\n ...(chosen.model ? { model: chosen.model } : {}),\n ...(chosen.thinking ? { thinking: chosen.thinking as never } : {}),\n ...(chosen.tools ? { tools: chosen.tools } : {}),\n prompts: given,\n origin: request.cwd,\n fromAgent: who.fromAgent,\n request: request.id,\n limits: found.roles.limits,\n },\n context\n );\n}\n\nasync function listAgents(deps: Deps): Promise<Answer> {\n const roles = await deps.roles();\n const lines = roles.roles.map(\n (entry) =>\n `${entry.name}\\t${entry.source}\\t${entry.description}${entry.aliases.length ? ` (also ${entry.aliases.join(', ')})` : ''}`\n );\n return ok(\n `${[\n ...lines,\n '',\n 'Agent files are read from the built-in roles, installed packages (pi-subagents.agents) and ~/.pi/agent/agents.',\n \"A project's .pi/agents folder is read only once the folder is trusted, which SLICC doesn't support yet.\",\n ...roles.warnings.map((warning) => `warning: ${warning}`),\n ].join('\\n')}\\n`\n );\n}\n\nasync function list(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n if (request.argv.includes('--agents')) return listAgents(deps);\n const rows = await deps.scoops.list(who.cone, context);\n if (!rows.length) return ok('no scoops\\n');\n return ok(\n `${rows.map((row) => `${row.folder}\\t${row.name}\\t${row.role ?? '-'}\\t${row.busy ? 'working' : 'idle'}`).join('\\n')}\\n`\n );\n}\n\nasync function status(\n deps: Deps,\n request: Request,\n who: Caller,\n context: Context\n): Promise<Answer> {\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n const [, record] = found;\n const busy = await deps.scoops.busy(record.conversation, context);\n return ok(\n `${[\n `handle: ${record.folder}`,\n `name: ${record.name}`,\n `role: ${record.role ?? '-'}`,\n `kind: ${record.kind}`,\n `state: ${busy ? 'working' : 'idle'}`,\n `folder: ${SCOOPS_ROOT}/${record.folder}`,\n `reports: ${SCOOPS_ROOT}/${record.folder}/reports`,\n ].join('\\n')}\\n`\n );\n}\n\nasync function message(\n deps: Deps,\n parsed: Flags,\n request: Request,\n context: Context\n): Promise<string> {\n const file = last(parsed, '--file');\n if (file) return readText(deps, file, request, context);\n return parsed.rest.includes('-') ? request.stdin : parsed.rest.join(' ');\n}\n\nasync function send(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n const parsed = flags(request.argv.slice(2), ['--file']);\n const unknown = [...parsed.switches].find((flag) => flag !== '--follow-up');\n if (unknown) return fail(`unknown option ${unknown}`, 2);\n const text = await message(deps, parsed, request, context);\n if (!text.trim()) return fail('send needs a message, --file or -', 2);\n if (request.argv[1] === 'parent') {\n if (!who.scoop) return fail('only a scoop has a parent to send to');\n return deps.scoops.note(who.scoop, text, context);\n }\n if (who.scoop) return fail('a scoop can only send to its parent');\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n const followUp = parsed.switches.has('--follow-up');\n return deps.scoops.feed(\n found[0],\n text,\n { fromAgent: who.fromAgent, request: request.id, followUp, target: who.id },\n context\n );\n}\n\nasync function latest(deps: Deps, folder: string, context: Context): Promise<string> {\n const dir = `${SCOOPS_ROOT}/${folder}/reports`;\n const listed = await deps.env.listDir(dir, context);\n if (!listed.ok || !listed.value.length) return '(no answer yet)';\n const newest = [...listed.value].sort(\n (a, b) => Number.parseInt(b.name, 10) - Number.parseInt(a.name, 10)\n )[0];\n const read = await deps.env.readTextFile(`${dir}/${newest?.name}`, context);\n return read.ok ? read.value.trimEnd() : '(no answer yet)';\n}\n\nfunction waitTargets(deps: Deps, who: Caller, rest: readonly string[]): string[] | Answer {\n if (!rest.length) return fail('wait needs at least one handle', 2);\n const missing = rest.filter((name) => !handle(deps, who, name));\n if (missing.length)\n return fail(missing.map((name) => noScoop(deps.agents.state(), name)).join('; '));\n return rest.map((name) => (handle(deps, who, name) as [string, unknown])[0]);\n}\n\nasync function block(\n deps: Deps,\n ids: string[],\n seconds: number,\n context: Context\n): Promise<Answer> {\n const deadline = deps.now() + seconds * 1000;\n let open = await deps.scoops.working(ids, context);\n while (open.length && deps.now() < deadline) {\n await new Promise((done) => setTimeout(done, 200));\n open = await deps.scoops.working(ids, context);\n }\n const state = deps.agents.state();\n const sections: string[] = [];\n for (const id of ids) {\n const record = state.scoops[id];\n if (record)\n sections.push(\n `## ${record.folder}${open.includes(id) ? ' (still working)' : ''}\\n${await latest(deps, record.folder, context)}`\n );\n }\n const body = `${sections.join('\\n\\n')}\\n`;\n if (!open.length) return ok(body);\n const still = open.map((id) => state.scoops[id]?.folder).join(', ');\n return { code: 1, out: `${body}agent: timed out after ${seconds}s; still working: ${still}\\n` };\n}\n\nasync function wait(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n const parsed = flags(request.argv.slice(1), ['--timeout']);\n const unknown = [...parsed.switches].find((flag) => flag !== '--notify');\n if (unknown) return fail(`unknown option ${unknown}`, 2);\n const seconds = Number(last(parsed, '--timeout') ?? DEFAULT_WAIT_S);\n if (!Number.isInteger(seconds) || seconds <= 0)\n return fail('--timeout must be a positive whole number of seconds', 2);\n const ids = waitTargets(deps, who, parsed.rest);\n if (isAnswer(ids)) return ids;\n if (!parsed.switches.has('--notify')) return block(deps, ids, seconds, context);\n if (!who.fromAgent || who.scoop)\n return fail('wait --notify is for a cone; a terminal waits with agent wait');\n await deps.scoops.notifyWhenDone(who.cone, ids, deps.now() + seconds * 1000, context);\n return ok(`you'll get one scoop-wait lick when ${ids.length > 1 ? 'they are' : 'it is'} done\\n`);\n}\n\nasync function stop(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n if (who.scoop) return fail('a scoop cannot stop scoops');\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n return deps.scoops.stop(found[0], who.fromAgent, context);\n}\n\nasync function rename(\n deps: Deps,\n request: Request,\n who: Caller,\n context: Context\n): Promise<Answer> {\n if (who.scoop) return fail('a scoop cannot rename scoops');\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n return deps.scoops.rename(found[0], request.argv.slice(2).join(' '), context);\n}\n\ntype Verb = (deps: Deps, request: Request, who: Caller, context: Context) => Promise<Answer>;\n\nconst help: Verb = async () => ok(USAGE);\n\nconst VERBS: Record<string, Verb> = {\n list,\n status,\n send,\n wait,\n stop,\n rename,\n help,\n '--help': help,\n '-h': help,\n __cancel: (deps, request, _who, context) => cancelSync(deps, request.argv[1] ?? '', context),\n __detach: (deps, request, _who, context) => detachSync(deps, request.argv[1] ?? '', context),\n};\n\nexport function noScoop(state: Readonly<AgentsState>, name: string): string {\n const id = name.startsWith('scoop:') ? name : `scoop:${name}`;\n const record =\n state.scoops[id]?.frozen !== undefined\n ? state.scoops[id]\n : Object.values(state.scoops).find(\n (candidate) => candidate.frozen && candidate.name === name\n );\n const frozen = record?.frozen ? state.frozen?.[record.frozen] : undefined;\n if (frozen) return `scoop ${name} is frozen with cone ${frozen.name}; thaw the cone first`;\n return `there is no scoop ${name}`.trim();\n}\n\nasync function dispatch(\n deps: Deps,\n request: Request,\n who: Caller,\n context: Context\n): Promise<Answer> {\n if (request.as === 'sprinkle')\n return deps.sprinkle\n ? deps.sprinkle(request.argv, who.id, context)\n : fail('sprinkles are not available in this agent');\n if (request.as === 'memory')\n return deps.memory\n ? deps.memory(request.argv, who.id, context)\n : fail('memory is not available in this agent');\n if (request.as === 'gelatiere')\n return deps.gelatiere\n ? deps.gelatiere(request.argv, who.id, context)\n : fail('the gelatiere is not available in this agent');\n if (request.as === 'freezer')\n return deps.freezer\n ? deps.freezer(request.argv, who.id, context)\n : fail('the freezer is not available in this agent');\n if (request.as === 'models')\n return deps.models\n ? deps.models(request.argv, who.id, context)\n : fail('models is not available in this agent');\n const first = request.argv[0] ?? '';\n const verb = VERBS[first];\n if (verb) return verb(deps, request, who, context);\n if (request.as === 'subagent') {\n if (first === 'spawn') return spawnAsync(deps, request, who, request.argv.slice(1), context);\n return { code: 2, out: USAGE };\n }\n if (!request.argv.length) return { code: 2, out: USAGE };\n if (request.argv.includes('--async'))\n return spawnAsync(deps, request, who, request.argv, context);\n return runSync(deps, request, who, context);\n}\n\nconst BLOCKING = new Set([\n 'wait',\n 'list',\n 'status',\n 'help',\n '--help',\n '-h',\n '__cancel',\n '__detach',\n]);\n\nexport function createCli(options: CliOptions): Runner {\n const deps: Deps = { ...options, now: options.now ?? Date.now, sync: { pending: new Map() } };\n return {\n blocking(request) {\n const first = request.argv[0] ?? '';\n if (BLOCKING.has(first)) return true;\n return request.as === 'agent' && !VERBS[first] && !request.argv.includes('--async');\n },\n async run(request, context) {\n try {\n return await dispatch(deps, request, callerOf(options.agents, request), context);\n } catch (error) {\n return fail((error as Error).message);\n }\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/scoops/index.js
CHANGED
|
@@ -2,10 +2,11 @@ import { live } from "../agents.js";
|
|
|
2
2
|
import { DEFAULT_LIMITS, loadRoles, packageDirs } from "../roles/roles.js";
|
|
3
3
|
import { createCli, RUN_DIR } from "./cli.js";
|
|
4
4
|
import { guardExtension, scoopsExtension, scoopTasks } from "./extension.js";
|
|
5
|
-
import { controlPlane } from "./requests.js";
|
|
5
|
+
import { controlPlane, PROTOCOL } from "./requests.js";
|
|
6
6
|
import { createScoops } from "./service.js";
|
|
7
7
|
const BUILTIN_ROLES = ["scout", "worker", "reviewer", "oracle", "delegate", "gelatiere"];
|
|
8
8
|
const PNPM_HOME = "/home/.local/share/pnpm";
|
|
9
|
+
const BIN_DIR = "/usr/local/bin";
|
|
9
10
|
function packageAssets(base = new URL("../../", import.meta.url)) {
|
|
10
11
|
return async (path) => {
|
|
11
12
|
const response = await fetch(new URL(path, base));
|
|
@@ -13,7 +14,15 @@ function packageAssets(base = new URL("../../", import.meta.url)) {
|
|
|
13
14
|
return response.text();
|
|
14
15
|
};
|
|
15
16
|
}
|
|
16
|
-
const COMMANDS = [
|
|
17
|
+
const COMMANDS = [
|
|
18
|
+
"agent",
|
|
19
|
+
"subagent",
|
|
20
|
+
"sprinkle",
|
|
21
|
+
"memory",
|
|
22
|
+
"gelatiere",
|
|
23
|
+
"freezer",
|
|
24
|
+
"models"
|
|
25
|
+
];
|
|
17
26
|
async function pnpmHomeOf(env, context) {
|
|
18
27
|
let out = "";
|
|
19
28
|
const ran = await env.exec(
|
|
@@ -27,12 +36,28 @@ async function pnpmHomeOf(env, context) {
|
|
|
27
36
|
).catch(() => void 0);
|
|
28
37
|
return ran?.ok && ran.value.exitCode === 0 && /^\/\S*$/.test(out) ? out : PNPM_HOME;
|
|
29
38
|
}
|
|
30
|
-
async function install(env, script,
|
|
31
|
-
await env.createDir(
|
|
39
|
+
async function install(env, script, binDir, context) {
|
|
40
|
+
if (!(await env.createDir(binDir, { recursive: true }, context)).ok) return false;
|
|
32
41
|
for (const name of COMMANDS) {
|
|
33
|
-
const path = `${
|
|
34
|
-
await env.writeFile(path, script, context);
|
|
35
|
-
await env.exec(["chmod", "
|
|
42
|
+
const path = `${binDir}/${name}`;
|
|
43
|
+
if (!(await env.writeFile(path, script, context)).ok) return false;
|
|
44
|
+
const mode = await env.exec(["chmod", "755", path], void 0, context);
|
|
45
|
+
if (!mode.ok || mode.value.exitCode !== 0) return false;
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
async function installCommands(env, script, binDir, context) {
|
|
50
|
+
const done = await install(env, script, binDir, context).catch(() => false);
|
|
51
|
+
if (done) await retire(env, binDir, context).catch(() => void 0);
|
|
52
|
+
return done;
|
|
53
|
+
}
|
|
54
|
+
async function retire(env, binDir, context) {
|
|
55
|
+
const old = `${await pnpmHomeOf(env, context)}/bin`;
|
|
56
|
+
if (old === binDir) return;
|
|
57
|
+
for (const name of COMMANDS) {
|
|
58
|
+
const path = `${old}/${name}`;
|
|
59
|
+
const text = await env.readTextFile(path, context);
|
|
60
|
+
if (text.ok && text.value.includes(PROTOCOL)) await env.remove(path, { force: true }, context);
|
|
36
61
|
}
|
|
37
62
|
}
|
|
38
63
|
function mirror(agents, env) {
|
|
@@ -111,8 +136,8 @@ function setupScoops(registry, licks, fileTools = []) {
|
|
|
111
136
|
await roles(context).catch(() => cached);
|
|
112
137
|
const script = await assets("bin/agent").catch(() => void 0);
|
|
113
138
|
if (script) {
|
|
114
|
-
const
|
|
115
|
-
await
|
|
139
|
+
const binDir = options.binDir ?? BIN_DIR;
|
|
140
|
+
await installCommands(env, script, binDir, context);
|
|
116
141
|
}
|
|
117
142
|
const cli = createCli({
|
|
118
143
|
env,
|
|
@@ -124,7 +149,8 @@ function setupScoops(registry, licks, fileTools = []) {
|
|
|
124
149
|
...options.sprinkle ? { sprinkle: options.sprinkle } : {},
|
|
125
150
|
...options.memory ? { memory: options.memory } : {},
|
|
126
151
|
...options.gelatiere ? { gelatiere: options.gelatiere } : {},
|
|
127
|
-
...options.freezer ? { freezer: options.freezer } : {}
|
|
152
|
+
...options.freezer ? { freezer: options.freezer } : {},
|
|
153
|
+
...options.models ? { models: options.models } : {}
|
|
128
154
|
});
|
|
129
155
|
const plane = controlPlane(env, cli, {
|
|
130
156
|
...options.controlDir ? { dir: options.controlDir } : {},
|
|
@@ -137,11 +163,14 @@ function setupScoops(registry, licks, fileTools = []) {
|
|
|
137
163
|
};
|
|
138
164
|
}
|
|
139
165
|
export {
|
|
166
|
+
BIN_DIR,
|
|
140
167
|
BUILTIN_ROLES,
|
|
141
168
|
COMMANDS,
|
|
142
169
|
PNPM_HOME,
|
|
170
|
+
installCommands,
|
|
143
171
|
packageAssets,
|
|
144
172
|
pnpmHomeOf,
|
|
173
|
+
retire,
|
|
145
174
|
setupScoops
|
|
146
175
|
};
|
|
147
176
|
//# sourceMappingURL=index.js.map
|
package/dist/scoops/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/scoops/index.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { Harness, Registry, ToolRegistration } from '@earendil-works/pi-durable';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport { type Agents, live } from '../agents.ts';\nimport type { ProcessGroups } from '../kernel/groups.ts';\nimport type { Licks } from '../licks/licks.ts';\nimport { DEFAULT_LIMITS, loadRoles, packageDirs, type Roles } from '../roles/roles.ts';\nimport { type CliOptions, createCli, RUN_DIR } from './cli.ts';\nimport { guardExtension, scoopsExtension, scoopTasks } from './extension.ts';\nimport { type ControlPlane, controlPlane } from './requests.ts';\nimport { createScoops, type Scoops, type ScoopsHost } from './service.ts';\n\nexport const BUILTIN_ROLES = ['scout', 'worker', 'reviewer', 'oracle', 'delegate', 'gelatiere'];\nexport const PNPM_HOME = '/home/.local/share/pnpm';\n\nexport type Assets = (path: string) => Promise<string>;\n\nexport function packageAssets(base: URL = new URL('../../', import.meta.url)): Assets {\n return async (path) => {\n const response = await fetch(new URL(path, base));\n if (!response.ok) throw new Error(`${path}: ${response.status}`);\n return response.text();\n };\n}\n\nexport interface AttachOptions {\n harness: Harness;\n agents: Agents;\n groups: ProcessGroups;\n env: ExecutionEnv;\n home: string;\n assets?: Assets;\n
|
|
5
|
-
"mappings": "AAGA,SAAsB,YAAY;AAGlC,SAAS,gBAAgB,WAAW,mBAA+B;AACnE,SAA0B,WAAW,eAAe;AACpD,SAAS,gBAAgB,iBAAiB,kBAAkB;AAC5D,SAA4B,
|
|
4
|
+
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { Harness, Registry, ToolRegistration } from '@earendil-works/pi-durable';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport { type Agents, live } from '../agents.ts';\nimport type { ProcessGroups } from '../kernel/groups.ts';\nimport type { Licks } from '../licks/licks.ts';\nimport { DEFAULT_LIMITS, loadRoles, packageDirs, type Roles } from '../roles/roles.ts';\nimport { type CliOptions, createCli, RUN_DIR } from './cli.ts';\nimport { guardExtension, scoopsExtension, scoopTasks } from './extension.ts';\nimport { type ControlPlane, controlPlane, PROTOCOL } from './requests.ts';\nimport { createScoops, type Scoops, type ScoopsHost } from './service.ts';\n\nexport const BUILTIN_ROLES = ['scout', 'worker', 'reviewer', 'oracle', 'delegate', 'gelatiere'];\nexport const PNPM_HOME = '/home/.local/share/pnpm';\nexport const BIN_DIR = '/usr/local/bin';\n\nexport type Assets = (path: string) => Promise<string>;\n\nexport function packageAssets(base: URL = new URL('../../', import.meta.url)): Assets {\n return async (path) => {\n const response = await fetch(new URL(path, base));\n if (!response.ok) throw new Error(`${path}: ${response.status}`);\n return response.text();\n };\n}\n\nexport interface AttachOptions {\n harness: Harness;\n agents: Agents;\n groups: ProcessGroups;\n env: ExecutionEnv;\n home: string;\n assets?: Assets;\n binDir?: string;\n controlDir?: string;\n sweepEvery?: number;\n alive?: (pid: number) => Promise<boolean>;\n reads: () => readonly string[];\n sprinkle?: CliOptions['sprinkle'];\n memory?: CliOptions['memory'];\n gelatiere?: CliOptions['gelatiere'];\n freezer?: CliOptions['freezer'];\n models?: CliOptions['models'];\n mcp?: (names: readonly string[]) => ToolRegistration[];\n}\n\nexport interface ScoopsRuntime {\n roles(context: Context): Promise<Roles>;\n plane: ControlPlane;\n close(context: Context): Promise<void>;\n}\n\nexport interface ScoopsSetup {\n scoops: Scoops;\n attach(options: AttachOptions, context: Context): Promise<ScoopsRuntime>;\n}\n\nexport const COMMANDS = [\n 'agent',\n 'subagent',\n 'sprinkle',\n 'memory',\n 'gelatiere',\n 'freezer',\n 'models',\n];\n\nexport async function pnpmHomeOf(env: ExecutionEnv, context: Context): Promise<string> {\n let out = '';\n const ran = await env\n .exec(\n 'printf %s \"$PNPM_HOME\"',\n {\n onOutput: (text) => {\n out += text;\n },\n },\n context\n )\n .catch(() => undefined);\n return ran?.ok && ran.value.exitCode === 0 && /^\\/\\S*$/.test(out) ? out : PNPM_HOME;\n}\n\nasync function install(env: ExecutionEnv, script: string, binDir: string, context: Context) {\n if (!(await env.createDir(binDir, { recursive: true }, context)).ok) return false;\n for (const name of COMMANDS) {\n const path = `${binDir}/${name}`;\n if (!(await env.writeFile(path, script, context)).ok) return false;\n const mode = await env.exec(['chmod', '755', path], undefined, context);\n if (!mode.ok || mode.value.exitCode !== 0) return false;\n }\n return true;\n}\n\nexport async function installCommands(\n env: ExecutionEnv,\n script: string,\n binDir: string,\n context: Context\n): Promise<boolean> {\n const done = await install(env, script, binDir, context).catch(() => false);\n if (done) await retire(env, binDir, context).catch(() => undefined);\n return done;\n}\n\nexport async function retire(env: ExecutionEnv, binDir: string, context: Context) {\n const old = `${await pnpmHomeOf(env, context)}/bin`;\n if (old === binDir) return;\n for (const name of COMMANDS) {\n const path = `${old}/${name}`;\n const text = await env.readTextFile(path, context);\n if (text.ok && text.value.includes(PROTOCOL)) await env.remove(path, { force: true }, context);\n }\n}\n\nfunction mirror(agents: Agents, env: ExecutionEnv) {\n return async (context: Context) => {\n for (const [id, record] of Object.entries(agents.state().scoops)) {\n const state = record.gone ? 'gone' : live(record) ? 'live' : 'stopped';\n const metadata = {\n handle: record.folder,\n id,\n name: record.name,\n role: record.role,\n cone: record.cone,\n state,\n };\n await env.writeFile(\n `${RUN_DIR}/${record.folder}/metadata.json`,\n `${JSON.stringify(metadata, null, 2)}\\n`,\n context\n );\n }\n };\n}\n\nexport function setupScoops(\n registry: Registry,\n licks: Licks,\n fileTools: readonly ToolRegistration[] = []\n): ScoopsSetup {\n let bind: (host: ScoopsHost) => void = () => undefined;\n const host = new Promise<ScoopsHost>((resolve) => {\n bind = resolve;\n });\n const lookup = () => host;\n const tasks = scoopTasks(lookup);\n const scoops = createScoops(host, () => tasks);\n let cached: Roles = { roles: [], warnings: [], limits: { ...DEFAULT_LIMITS } };\n registry.install(scoopsExtension(tasks));\n registry.install(guardExtension(lookup, fileTools));\n return {\n scoops,\n async attach(options, context) {\n const { harness, agents, groups, env, home } = options;\n const assets = options.assets ?? packageAssets();\n bind({\n harness,\n agents,\n licks,\n tools: fileTools,\n groups,\n reads: options.reads,\n files: env,\n ...(options.mcp ? { mcp: options.mcp } : {}),\n });\n const builtin = async () => {\n const out: { path: string; text: string }[] = [];\n for (const name of BUILTIN_ROLES) {\n const path = `packages/vfs-root/agents/${name}.md`;\n out.push({ path: `builtin:${name}`, text: await assets(path) });\n }\n return out;\n };\n const roles = async (using: Context) => {\n cached = await loadRoles(\n {\n files: env,\n builtin,\n dirs: [\n ...(await packageDirs(env, '/node_modules', using)).map((dir) => ({\n source: 'package' as const,\n dir,\n })),\n { source: 'user', dir: `${home}/.pi/agent/agents` },\n ],\n settingsPath: `${home}/.pi/agent/settings.json`,\n },\n using\n );\n return cached;\n };\n await roles(context).catch(() => cached);\n const script = await assets('bin/agent').catch(() => undefined);\n if (script) {\n const binDir = options.binDir ?? BIN_DIR;\n await installCommands(env, script, binDir, context);\n }\n const cli = createCli({\n env,\n harness,\n agents,\n scoops,\n roles: () => roles(context),\n ...(options.alive ? { alive: options.alive } : {}),\n ...(options.sprinkle ? { sprinkle: options.sprinkle } : {}),\n ...(options.memory ? { memory: options.memory } : {}),\n ...(options.gelatiere ? { gelatiere: options.gelatiere } : {}),\n ...(options.freezer ? { freezer: options.freezer } : {}),\n ...(options.models ? { models: options.models } : {}),\n });\n const plane = controlPlane(env, cli, {\n ...(options.controlDir ? { dir: options.controlDir } : {}),\n ...(options.sweepEvery ? { sweepEvery: options.sweepEvery } : {}),\n mirror: mirror(agents, env),\n });\n await plane.start(context);\n return { roles, plane, close: (using) => plane.close(using) };\n },\n };\n}\n\nexport type { Rewound, Scoops } from './service.ts';\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|