pi-crew 0.2.9 → 0.2.11
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/package.json
CHANGED
|
@@ -3,6 +3,7 @@ import { Type } from "@sinclair/typebox";
|
|
|
3
3
|
import type { TeamToolParamsValue } from "../../schema/team-tool-schema.ts";
|
|
4
4
|
// Lazy-loaded: team-tool.ts pulls in entire runtime chain.
|
|
5
5
|
import type { handleTeamTool as HandleTeamToolFn } from "../team-tool.ts";
|
|
6
|
+
import { withSessionId } from "../team-tool/context.ts";
|
|
6
7
|
let _cachedHandleTeamTool: typeof HandleTeamToolFn | undefined;
|
|
7
8
|
async function handleTeamTool(params: Parameters<typeof HandleTeamToolFn>[0], ctx: Parameters<typeof HandleTeamToolFn>[1]): Promise<Awaited<ReturnType<typeof HandleTeamToolFn>>> {
|
|
8
9
|
if (!_cachedHandleTeamTool) {
|
|
@@ -63,7 +64,10 @@ export function registerSubagentTools(pi: ExtensionAPI, subagentManager: Subagen
|
|
|
63
64
|
const spawnOptions = __test__subagentSpawnParams(params as Record<string, unknown>, ctx);
|
|
64
65
|
spawnOptions.ownerSessionGeneration = options.ownerSessionGeneration?.();
|
|
65
66
|
if (!spawnOptions.prompt.trim()) return subagentToolResult(t("agent.requiresPrompt"), {}, true);
|
|
66
|
-
|
|
67
|
+
// Extract sessionId from sessionManager.getSessionId() so team runs created
|
|
68
|
+
// by the Agent tool have proper session ownership for isolation.
|
|
69
|
+
const ctxWithSession = withSessionId(ctx);
|
|
70
|
+
const runner = async (currentOptions: SubagentSpawnOptions, childSignal?: AbortSignal) => handleTeamTool({ action: "run", agent: currentOptions.type, goal: currentOptions.prompt, model: currentOptions.model, skill: currentOptions.skill, async: currentOptions.background, config: currentOptions.maxTurns ? { runtime: { maxTurns: currentOptions.maxTurns } } : undefined } as TeamToolParamsValue, { ...ctxWithSession, signal: childSignal, ...(options.startForegroundRun ? { startForegroundRun: (runRunner: (sig?: AbortSignal) => Promise<void>, runId?: string) => options.startForegroundRun!(ctxWithSession, runRunner, runId) } : {}) });
|
|
67
71
|
const record = subagentManager.spawn(spawnOptions, runner, spawnOptions.background ? undefined : signal);
|
|
68
72
|
if (spawnOptions.background || record.status === "queued") {
|
|
69
73
|
// Phase 1.1a: Terminate turn for background queued — no LLM follow-up needed.
|
|
@@ -201,7 +201,7 @@ export async function handleRun(params: TeamToolParamsValue, ctx: TeamContext):
|
|
|
201
201
|
ctx.onRunStarted?.(updatedManifest.runId);
|
|
202
202
|
ctx.startForegroundRun(async (signal) => {
|
|
203
203
|
try {
|
|
204
|
-
await executeTeamRun({ manifest: executionManifest, tasks, team, workflow, agents, executeWorkers, limits: executedConfig.limits, runtime, runtimeConfig: executedConfig.runtime, parentContext: buildParentContext(ctx), parentModel: ctx.model, modelRegistry: ctx.modelRegistry, modelOverride: params.model, skillOverride, signal, reliability: executedConfig.reliability, metricRegistry: ctx.metricRegistry, onJsonEvent: ctx.onJsonEvent, workspaceId: ctx.cwd });
|
|
204
|
+
await executeTeamRun({ manifest: executionManifest, tasks, team, workflow, agents, executeWorkers, limits: executedConfig.limits, runtime, runtimeConfig: executedConfig.runtime, parentContext: buildParentContext(ctx), parentModel: ctx.model, modelRegistry: ctx.modelRegistry, modelOverride: params.model, skillOverride, signal, reliability: executedConfig.reliability, metricRegistry: ctx.metricRegistry, onJsonEvent: ctx.onJsonEvent, workspaceId: ctx.sessionId ?? ctx.cwd });
|
|
205
205
|
} finally {
|
|
206
206
|
unregisterActiveRun(updatedManifest.runId);
|
|
207
207
|
}
|
|
@@ -237,7 +237,7 @@ export async function handleResume(params: TeamToolParamsValue, ctx: TeamContext
|
|
|
237
237
|
if (replay.messages.length) appendEvent(runtimeManifest.eventsPath, { type: "mailbox.replayed", runId: runtimeManifest.runId, message: `Replayed ${replay.messages.length} pending inbox message(s).`, data: { messageIds: replay.messages.map((message) => message.id), taskIds: replay.messages.map((message) => message.taskId).filter(Boolean) } });
|
|
238
238
|
const executeWorkers = runtime.kind !== "scaffold";
|
|
239
239
|
const resumeSkillOverride = normalizeSkillOverride(params.skill) ?? runtimeManifest.skillOverride;
|
|
240
|
-
const executed = await executeTeamRun({ manifest: runtimeManifest, tasks: resetTasks, team, workflow, agents, executeWorkers, limits: executedConfig.limits, runtime, runtimeConfig: executedConfig.runtime, parentContext: buildParentContext(ctx), parentModel: ctx.model, modelRegistry: ctx.modelRegistry, modelOverride: params.model, skillOverride: resumeSkillOverride, signal: ctx.signal, reliability: executedConfig.reliability, metricRegistry: ctx.metricRegistry, workspaceId: ctx.cwd });
|
|
240
|
+
const executed = await executeTeamRun({ manifest: runtimeManifest, tasks: resetTasks, team, workflow, agents, executeWorkers, limits: executedConfig.limits, runtime, runtimeConfig: executedConfig.runtime, parentContext: buildParentContext(ctx), parentModel: ctx.model, modelRegistry: ctx.modelRegistry, modelOverride: params.model, skillOverride: resumeSkillOverride, signal: ctx.signal, reliability: executedConfig.reliability, metricRegistry: ctx.metricRegistry, workspaceId: ctx.sessionId ?? ctx.cwd });
|
|
241
241
|
return result([`Resumed run ${executed.manifest.runId}.`, `Status: ${executed.manifest.status}`, `Tasks: ${executed.tasks.length}`, `Artifacts: ${executed.manifest.artifactsRoot}`].join("\n"), { action: "resume", status: executed.manifest.status === "failed" ? "error" : "ok", runId: executed.manifest.runId, artifactsRoot: executed.manifest.artifactsRoot }, executed.manifest.status === "failed");
|
|
242
242
|
});
|
|
243
243
|
}
|
|
@@ -130,7 +130,9 @@ async function main(): Promise<void> {
|
|
|
130
130
|
appendEvent(manifest.eventsPath, { type: "runtime.resolved", runId: manifest.runId, message: `Runtime resolved: ${runtime.kind} safety=${runtime.safety}`, data: { runtimeResolution, async: true } });
|
|
131
131
|
if (runtime.safety === "blocked") throw new Error(runtime.reason ?? "Child worker execution is disabled; refusing to create no-op scaffold subagents.");
|
|
132
132
|
const executeWorkers = runtime.kind !== "scaffold";
|
|
133
|
-
|
|
133
|
+
// Use ownerSessionId for workspaceId to ensure agents are only visible to the session that spawned them.
|
|
134
|
+
// manifest.cwd would cause cross-session visibility since all sessions share the same project directory.
|
|
135
|
+
const result = await executeTeamRun({ manifest, tasks, team, workflow, agents, executeWorkers, limits: runConfig.limits, runtime, runtimeConfig: runConfig.runtime, skillOverride: manifest.skillOverride, reliability: runConfig.reliability, workspaceId: manifest.ownerSessionId ?? manifest.cwd });
|
|
134
136
|
manifest = result.manifest;
|
|
135
137
|
tasks = result.tasks;
|
|
136
138
|
appendEvent(manifest.eventsPath, { type: "async.completed", runId: manifest.runId, data: { status: manifest.status, tasks: tasks.length } });
|