@evandu/super-pi 0.1.46 → 0.1.48
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/agents/super-pi-task/core.ts +36 -1
- package/dist/client/assets/index-gfrkA0G7.js +53 -0
- package/dist/client/assets/index-u2f9ElVe.css +1 -0
- package/dist/client/index.html +2 -2
- package/dist/server/index.js +2 -1
- package/dist/server/runtime.d.ts +1 -0
- package/dist/server/runtime.js +2 -1
- package/dist/server/task-tool.d.ts +2 -0
- package/dist/server/task-tool.js +2 -0
- package/package.json +1 -1
- package/dist/client/assets/index-R__tXj9x.js +0 -53
- package/dist/client/assets/index-nrvfPezO.css +0 -1
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
*/
|
|
39
39
|
export const TASK_TOOL_NAME = "task";
|
|
40
40
|
export const TASK_ENDPOINT_ENV = "SUPER_PI_TASK_ENDPOINT";
|
|
41
|
+
export const TASK_EXEC_ENDPOINT_ENV = "SUPER_PI_EXEC_ENDPOINT";
|
|
41
42
|
export const TASK_ROSTER_ENV = "SUPER_PI_TASK_ROSTER";
|
|
42
43
|
export const TASK_CONVERSATION_ENV = "SUPER_PI_TASK_CONVERSATION";
|
|
43
44
|
export const TASK_DEPTH_ENV = "SUPER_PI_TASK_DEPTH";
|
|
@@ -200,6 +201,8 @@ export function renderTaskResult(input: { id: string; state: "completed" | "erro
|
|
|
200
201
|
/** What the extension learns from its own environment before it can dispatch anything. */
|
|
201
202
|
export type TaskToolConfig = {
|
|
202
203
|
endpoint: string;
|
|
204
|
+
/** The exec endpoint for background shell commands. Opaque to the caller. */
|
|
205
|
+
execEndpoint: string;
|
|
203
206
|
conversationId: string;
|
|
204
207
|
depth: number;
|
|
205
208
|
roster: RosterEntry[];
|
|
@@ -223,6 +226,7 @@ export function readTaskConfig(env: Record<string, string | undefined>): TaskToo
|
|
|
223
226
|
const capability = env[TASK_CAPABILITY_ENV];
|
|
224
227
|
return {
|
|
225
228
|
endpoint: env[TASK_ENDPOINT_ENV] ?? "",
|
|
229
|
+
execEndpoint: env[TASK_EXEC_ENDPOINT_ENV] ?? "",
|
|
226
230
|
conversationId: env[TASK_CONVERSATION_ENV] ?? "",
|
|
227
231
|
// An unreadable depth is 0, the primary agent's own value, rather than a number that would claim to
|
|
228
232
|
// be nested and trip the server's refusal for a reason that has nothing to do with this call.
|
|
@@ -258,6 +262,7 @@ export function refuseTask(config: TaskToolConfig, params: TaskParams): string |
|
|
|
258
262
|
if (!params.subagent_type.trim()) return `subagent_type is required. Available: ${config.roster.map((entry) => entry.id).join(", ")}.`;
|
|
259
263
|
if (!config.roster.some((entry) => entry.id === params.subagent_type)) return `${JSON.stringify(params.subagent_type)} is not a dispatchable subagent_type. Available: ${config.roster.map((entry) => entry.id).join(", ")}. Pick one of those, or do the work yourself.`;
|
|
260
264
|
if (!params.prompt.trim()) return "prompt is required and must not be empty: the sub-agent starts with a fresh context and your prompt is everything it will know.";
|
|
265
|
+
if (params.background === true && !config.execEndpoint) return `Background tasks are not available: ${TASK_EXEC_ENDPOINT_ENV} is not set. Do the work yourself with your other tools.`;
|
|
261
266
|
return undefined;
|
|
262
267
|
}
|
|
263
268
|
|
|
@@ -284,6 +289,36 @@ export async function executeTask(
|
|
|
284
289
|
const refusal = refuseTask(config, params);
|
|
285
290
|
if (refusal) return text(renderTaskResult({ id: "refused", state: "error", text: refusal }), true);
|
|
286
291
|
|
|
292
|
+
// Background: true uses the lightweight exec endpoint instead of the subagent dispatcher.
|
|
293
|
+
// This avoids spawning a full Pi agent process for a plain shell command.
|
|
294
|
+
if (params.background === true && config.execEndpoint) {
|
|
295
|
+
const send = deps.fetch ?? globalFetch;
|
|
296
|
+
let response: Awaited<ReturnType<TaskFetch>>;
|
|
297
|
+
try {
|
|
298
|
+
response = await send(config.execEndpoint, {
|
|
299
|
+
method: "POST",
|
|
300
|
+
headers: { "content-type": "application/json", ...(config.token ? { authorization: `Bearer ${config.token}` } : {}) },
|
|
301
|
+
body: JSON.stringify({
|
|
302
|
+
cmd: params.prompt,
|
|
303
|
+
cwd: context.cwd,
|
|
304
|
+
conversationId: config.conversationId,
|
|
305
|
+
capability: config.capability,
|
|
306
|
+
}),
|
|
307
|
+
...(deps.signal ? { signal: deps.signal } : {}),
|
|
308
|
+
});
|
|
309
|
+
} catch (error) {
|
|
310
|
+
return text(renderTaskResult({ id: "unreachable", state: "error", text: `Could not reach the Super Pi server at ${config.execEndpoint}: ${error instanceof Error ? error.message : "unknown error"}` }), true);
|
|
311
|
+
}
|
|
312
|
+
let payload: { sessionId?: string; status?: string; error?: string };
|
|
313
|
+
try { payload = JSON.parse(await response.text()) as typeof payload; }
|
|
314
|
+
catch { return text(renderTaskResult({ id: "unreadable", state: "error", text: `The exec endpoint answered ${response.status} with something that is not JSON.` }), true); }
|
|
315
|
+
const id = payload.sessionId ?? "refused";
|
|
316
|
+
if (payload.status === "running") {
|
|
317
|
+
return text(`<task id="${id}" state="running">\n<summary>${params.description.trim() || params.prompt.slice(0, 60)}</summary>\n<task_result>The command is running in the background. You will be notified automatically when it finishes. Do not sleep, poll for progress, or duplicate this work. Continue with non-overlapping work.</task_result>\n</task>`);
|
|
318
|
+
}
|
|
319
|
+
return text(renderTaskResult({ id, state: "error", text: payload.error ?? `Exec endpoint returned status ${payload.status}` }), true);
|
|
320
|
+
}
|
|
321
|
+
|
|
287
322
|
const send = deps.fetch ?? globalFetch;
|
|
288
323
|
let response: Awaited<ReturnType<TaskFetch>>;
|
|
289
324
|
try {
|
|
@@ -298,7 +333,7 @@ export async function executeTask(
|
|
|
298
333
|
prompt: params.prompt,
|
|
299
334
|
description: params.description,
|
|
300
335
|
depth: config.depth,
|
|
301
|
-
background:
|
|
336
|
+
background: false,
|
|
302
337
|
// Always sent, even when undefined, so a body that omits the field is unambiguously a caller that
|
|
303
338
|
// did not have one - which the server treats as a refusal, not as a legacy request to let through.
|
|
304
339
|
capability: config.capability,
|