refactor(agents): unify spawned metadata and extract attachments service

This commit is contained in:
Peter Steinberger
2026-03-08 00:23:28 +00:00
parent 61000b8e4d
commit eed403dc74
9 changed files with 675 additions and 350 deletions

View File

@@ -36,6 +36,7 @@ import {
import { runEmbeddedPiAgent } from "../agents/pi-embedded.js";
import { buildWorkspaceSkillSnapshot } from "../agents/skills.js";
import { getSkillsSnapshotVersion } from "../agents/skills/refresh.js";
import { normalizeSpawnedRunMetadata } from "../agents/spawned-context.js";
import { resolveAgentTimeoutMs } from "../agents/timeout.js";
import { ensureAgentWorkspace } from "../agents/workspace.js";
import { normalizeReplyPayload } from "../auto-reply/reply/normalize-reply.js";
@@ -416,10 +417,9 @@ function runAgentAttempt(params: {
});
}
async function agentCommandInternal(
async function prepareAgentCommandExecution(
opts: AgentCommandOpts & { senderIsOwner: boolean },
runtime: RuntimeEnv = defaultRuntime,
deps: CliDeps = createDefaultDeps(),
runtime: RuntimeEnv,
) {
const message = (opts.message ?? "").trim();
if (!message) {
@@ -448,6 +448,13 @@ async function agentCommandInternal(
targetIds: getAgentRuntimeCommandSecretTargetIds(),
});
setRuntimeConfigSnapshot(cfg, sourceConfig);
const normalizedSpawned = normalizeSpawnedRunMetadata({
spawnedBy: opts.spawnedBy,
groupId: opts.groupId,
groupChannel: opts.groupChannel,
groupSpace: opts.groupSpace,
workspaceDir: opts.workspaceDir,
});
for (const entry of diagnostics) {
runtime.log(`[secrets] ${entry}`);
}
@@ -521,7 +528,7 @@ async function agentCommandInternal(
const {
sessionId,
sessionKey,
sessionEntry: resolvedSessionEntry,
sessionEntry: sessionEntryRaw,
sessionStore,
storePath,
isNewSession,
@@ -541,14 +548,13 @@ async function agentCommandInternal(
});
// Internal callers (for example subagent spawns) may pin workspace inheritance.
const workspaceDirRaw =
opts.workspaceDir?.trim() ?? resolveAgentWorkspaceDir(cfg, sessionAgentId);
normalizedSpawned.workspaceDir ?? resolveAgentWorkspaceDir(cfg, sessionAgentId);
const agentDir = resolveAgentDir(cfg, sessionAgentId);
const workspace = await ensureAgentWorkspace({
dir: workspaceDirRaw,
ensureBootstrapFiles: !agentCfg?.skipBootstrap,
});
const workspaceDir = workspace.dir;
let sessionEntry = resolvedSessionEntry;
const runId = opts.runId?.trim() || sessionId;
const acpManager = getAcpSessionManager();
const acpResolution = sessionKey
@@ -558,6 +564,65 @@ async function agentCommandInternal(
})
: null;
return {
body,
cfg,
normalizedSpawned,
agentCfg,
thinkOverride,
thinkOnce,
verboseOverride,
timeoutMs,
sessionId,
sessionKey,
sessionEntry: sessionEntryRaw,
sessionStore,
storePath,
isNewSession,
persistedThinking,
persistedVerbose,
sessionAgentId,
outboundSession,
workspaceDir,
agentDir,
runId,
acpManager,
acpResolution,
};
}
async function agentCommandInternal(
opts: AgentCommandOpts & { senderIsOwner: boolean },
runtime: RuntimeEnv = defaultRuntime,
deps: CliDeps = createDefaultDeps(),
) {
const prepared = await prepareAgentCommandExecution(opts, runtime);
const {
body,
cfg,
normalizedSpawned,
agentCfg,
thinkOverride,
thinkOnce,
verboseOverride,
timeoutMs,
sessionId,
sessionKey,
sessionStore,
storePath,
isNewSession,
persistedThinking,
persistedVerbose,
sessionAgentId,
outboundSession,
workspaceDir,
agentDir,
runId,
acpManager,
acpResolution,
} = prepared;
let sessionEntry = prepared.sessionEntry;
try {
if (opts.deliver === true) {
const sendPolicy = resolveSendPolicy({
@@ -919,7 +984,7 @@ async function agentCommandInternal(
runContext.messageChannel,
opts.replyChannel ?? opts.channel,
);
const spawnedBy = opts.spawnedBy ?? sessionEntry?.spawnedBy;
const spawnedBy = normalizedSpawned.spawnedBy ?? sessionEntry?.spawnedBy;
// Keep fallback candidate resolution centralized so session model overrides,
// per-agent overrides, and default fallbacks stay consistent across callers.
const effectiveFallbacksOverride = resolveEffectiveModelFallbacks({

View File

@@ -1,5 +1,6 @@
import type { AgentInternalEvent } from "../../agents/internal-events.js";
import type { ClientToolDefinition } from "../../agents/pi-embedded-runner/run/params.js";
import type { SpawnedRunMetadata } from "../../agents/spawned-context.js";
import type { ChannelOutboundTargetMode } from "../../channels/plugins/types.js";
import type { InputProvenance } from "../../sessions/input-provenance.js";
@@ -62,14 +63,11 @@ export type AgentCommandOpts = {
runContext?: AgentRunContext;
/** Whether this caller is authorized for owner-only tools (defaults true for local CLI calls). */
senderIsOwner?: boolean;
/** Group id for channel-level tool policy resolution. */
groupId?: string | null;
/** Group channel label for channel-level tool policy resolution. */
groupChannel?: string | null;
/** Group space label for channel-level tool policy resolution. */
groupSpace?: string | null;
/** Parent session key for subagent policy inheritance. */
spawnedBy?: string | null;
/** Group/spawn metadata for subagent policy inheritance and routing context. */
groupId?: SpawnedRunMetadata["groupId"];
groupChannel?: SpawnedRunMetadata["groupChannel"];
groupSpace?: SpawnedRunMetadata["groupSpace"];
spawnedBy?: SpawnedRunMetadata["spawnedBy"];
deliveryTargetMode?: ChannelOutboundTargetMode;
bestEffortDeliver?: boolean;
abortSignal?: AbortSignal;
@@ -81,7 +79,7 @@ export type AgentCommandOpts = {
/** Per-call stream param overrides (best-effort). */
streamParams?: AgentStreamParams;
/** Explicit workspace directory override (for subagents to inherit parent workspace). */
workspaceDir?: string;
workspaceDir?: SpawnedRunMetadata["workspaceDir"];
};
export type AgentCommandIngressOpts = Omit<AgentCommandOpts, "senderIsOwner"> & {