refactor(auto-reply): reuse embedded run context helpers

This commit is contained in:
Peter Steinberger
2026-02-17 00:10:26 +00:00
parent 246bb7f30f
commit 423b7a0f28
4 changed files with 89 additions and 56 deletions

View File

@@ -34,7 +34,12 @@ import {
} from "../../utils/message-channel.js"; } from "../../utils/message-channel.js";
import { stripHeartbeatToken } from "../heartbeat.js"; import { stripHeartbeatToken } from "../heartbeat.js";
import { isSilentReplyText, SILENT_REPLY_TOKEN } from "../tokens.js"; import { isSilentReplyText, SILENT_REPLY_TOKEN } from "../tokens.js";
import { buildThreadingToolContext, resolveEnforceFinalTag } from "./agent-runner-utils.js"; import {
buildEmbeddedContextFromTemplate,
buildTemplateSenderContext,
resolveEnforceFinalTag,
resolveRunAuthProfile,
} from "./agent-runner-utils.js";
import { type BlockReplyPipeline } from "./block-reply-pipeline.js"; import { type BlockReplyPipeline } from "./block-reply-pipeline.js";
import { createBlockReplyDeliveryHandler } from "./reply-delivery.js"; import { createBlockReplyDeliveryHandler } from "./reply-delivery.js";
@@ -257,32 +262,20 @@ export async function runAgentTurnWithFallback(params: {
} }
})(); })();
} }
const authProfileId = const authProfile = resolveRunAuthProfile(params.followupRun.run, provider);
provider === params.followupRun.run.provider const embeddedContext = buildEmbeddedContextFromTemplate({
? params.followupRun.run.authProfileId run: params.followupRun.run,
: undefined; sessionCtx: params.sessionCtx,
hasRepliedRef: params.opts?.hasRepliedRef,
});
const senderContext = buildTemplateSenderContext(params.sessionCtx);
return runEmbeddedPiAgent({ return runEmbeddedPiAgent({
sessionId: params.followupRun.run.sessionId, ...embeddedContext,
sessionKey: params.sessionKey,
agentId: params.followupRun.run.agentId,
messageProvider: params.sessionCtx.Provider?.trim().toLowerCase() || undefined,
agentAccountId: params.sessionCtx.AccountId,
messageTo: params.sessionCtx.OriginatingTo ?? params.sessionCtx.To,
messageThreadId: params.sessionCtx.MessageThreadId ?? undefined,
groupId: resolveGroupSessionKey(params.sessionCtx)?.id, groupId: resolveGroupSessionKey(params.sessionCtx)?.id,
groupChannel: groupChannel:
params.sessionCtx.GroupChannel?.trim() ?? params.sessionCtx.GroupSubject?.trim(), params.sessionCtx.GroupChannel?.trim() ?? params.sessionCtx.GroupSubject?.trim(),
groupSpace: params.sessionCtx.GroupSpace?.trim() ?? undefined, groupSpace: params.sessionCtx.GroupSpace?.trim() ?? undefined,
senderId: params.sessionCtx.SenderId?.trim() || undefined, ...senderContext,
senderName: params.sessionCtx.SenderName?.trim() || undefined,
senderUsername: params.sessionCtx.SenderUsername?.trim() || undefined,
senderE164: params.sessionCtx.SenderE164?.trim() || undefined,
// Provider threading context for tool auto-injection
...buildThreadingToolContext({
sessionCtx: params.sessionCtx,
config: params.followupRun.run.config,
hasRepliedRef: params.opts?.hasRepliedRef,
}),
sessionFile: params.followupRun.run.sessionFile, sessionFile: params.followupRun.run.sessionFile,
workspaceDir: params.followupRun.run.workspaceDir, workspaceDir: params.followupRun.run.workspaceDir,
agentDir: params.followupRun.run.agentDir, agentDir: params.followupRun.run.agentDir,
@@ -294,10 +287,7 @@ export async function runAgentTurnWithFallback(params: {
enforceFinalTag: resolveEnforceFinalTag(params.followupRun.run, provider), enforceFinalTag: resolveEnforceFinalTag(params.followupRun.run, provider),
provider, provider,
model, model,
authProfileId, ...authProfile,
authProfileIdSource: authProfileId
? params.followupRun.run.authProfileIdSource
: undefined,
thinkLevel: params.followupRun.run.thinkLevel, thinkLevel: params.followupRun.run.thinkLevel,
verboseLevel: params.followupRun.run.verboseLevel, verboseLevel: params.followupRun.run.verboseLevel,
reasoningLevel: params.followupRun.run.reasoningLevel, reasoningLevel: params.followupRun.run.reasoningLevel,

View File

@@ -16,7 +16,12 @@ import {
} from "../../config/sessions.js"; } from "../../config/sessions.js";
import { logVerbose } from "../../globals.js"; import { logVerbose } from "../../globals.js";
import { registerAgentRunContext } from "../../infra/agent-events.js"; import { registerAgentRunContext } from "../../infra/agent-events.js";
import { buildThreadingToolContext, resolveEnforceFinalTag } from "./agent-runner-utils.js"; import {
buildEmbeddedContextFromTemplate,
buildTemplateSenderContext,
resolveEnforceFinalTag,
resolveRunAuthProfile,
} from "./agent-runner-utils.js";
import { import {
resolveMemoryFlushContextWindowTokens, resolveMemoryFlushContextWindowTokens,
resolveMemoryFlushPromptForRun, resolveMemoryFlushPromptForRun,
@@ -107,28 +112,16 @@ export async function runMemoryFlushIfNeeded(params: {
resolveAgentIdFromSessionKey(params.followupRun.run.sessionKey), resolveAgentIdFromSessionKey(params.followupRun.run.sessionKey),
), ),
run: (provider, model) => { run: (provider, model) => {
const authProfileId = const authProfile = resolveRunAuthProfile(params.followupRun.run, provider);
provider === params.followupRun.run.provider const embeddedContext = buildEmbeddedContextFromTemplate({
? params.followupRun.run.authProfileId run: params.followupRun.run,
: undefined; sessionCtx: params.sessionCtx,
hasRepliedRef: params.opts?.hasRepliedRef,
});
const senderContext = buildTemplateSenderContext(params.sessionCtx);
return runEmbeddedPiAgent({ return runEmbeddedPiAgent({
sessionId: params.followupRun.run.sessionId, ...embeddedContext,
sessionKey: params.sessionKey, ...senderContext,
agentId: params.followupRun.run.agentId,
messageProvider: params.sessionCtx.Provider?.trim().toLowerCase() || undefined,
agentAccountId: params.sessionCtx.AccountId,
messageTo: params.sessionCtx.OriginatingTo ?? params.sessionCtx.To,
messageThreadId: params.sessionCtx.MessageThreadId ?? undefined,
// Provider threading context for tool auto-injection
...buildThreadingToolContext({
sessionCtx: params.sessionCtx,
config: params.followupRun.run.config,
hasRepliedRef: params.opts?.hasRepliedRef,
}),
senderId: params.sessionCtx.SenderId?.trim() || undefined,
senderName: params.sessionCtx.SenderName?.trim() || undefined,
senderUsername: params.sessionCtx.SenderUsername?.trim() || undefined,
senderE164: params.sessionCtx.SenderE164?.trim() || undefined,
sessionFile: params.followupRun.run.sessionFile, sessionFile: params.followupRun.run.sessionFile,
workspaceDir: params.followupRun.run.workspaceDir, workspaceDir: params.followupRun.run.workspaceDir,
agentDir: params.followupRun.run.agentDir, agentDir: params.followupRun.run.agentDir,
@@ -143,10 +136,7 @@ export async function runMemoryFlushIfNeeded(params: {
enforceFinalTag: resolveEnforceFinalTag(params.followupRun.run, provider), enforceFinalTag: resolveEnforceFinalTag(params.followupRun.run, provider),
provider, provider,
model, model,
authProfileId, ...authProfile,
authProfileIdSource: authProfileId
? params.followupRun.run.authProfileIdSource
: undefined,
thinkLevel: params.followupRun.run.thinkLevel, thinkLevel: params.followupRun.run.thinkLevel,
verboseLevel: params.followupRun.run.verboseLevel, verboseLevel: params.followupRun.run.verboseLevel,
reasoningLevel: params.followupRun.run.reasoningLevel, reasoningLevel: params.followupRun.run.reasoningLevel,

View File

@@ -134,3 +134,57 @@ export const appendUsageLine = (payloads: ReplyPayload[], line: string): ReplyPa
export const resolveEnforceFinalTag = (run: FollowupRun["run"], provider: string) => export const resolveEnforceFinalTag = (run: FollowupRun["run"], provider: string) =>
Boolean(run.enforceFinalTag || isReasoningTagProvider(provider)); Boolean(run.enforceFinalTag || isReasoningTagProvider(provider));
export function buildEmbeddedContextFromTemplate(params: {
run: FollowupRun["run"];
sessionCtx: TemplateContext;
hasRepliedRef: { value: boolean } | undefined;
}) {
return {
sessionId: params.run.sessionId,
sessionKey: params.run.sessionKey,
agentId: params.run.agentId,
messageProvider: params.sessionCtx.Provider?.trim().toLowerCase() || undefined,
agentAccountId: params.sessionCtx.AccountId,
messageTo: params.sessionCtx.OriginatingTo ?? params.sessionCtx.To,
messageThreadId: params.sessionCtx.MessageThreadId ?? undefined,
// Provider threading context for tool auto-injection
...buildThreadingToolContext({
sessionCtx: params.sessionCtx,
config: params.run.config,
hasRepliedRef: params.hasRepliedRef,
}),
};
}
export function buildTemplateSenderContext(sessionCtx: TemplateContext) {
return {
senderId: sessionCtx.SenderId?.trim() || undefined,
senderName: sessionCtx.SenderName?.trim() || undefined,
senderUsername: sessionCtx.SenderUsername?.trim() || undefined,
senderE164: sessionCtx.SenderE164?.trim() || undefined,
};
}
export function resolveRunAuthProfile(run: FollowupRun["run"], provider: string) {
return resolveProviderScopedAuthProfile({
provider,
primaryProvider: run.provider,
authProfileId: run.authProfileId,
authProfileIdSource: run.authProfileIdSource,
});
}
export function resolveProviderScopedAuthProfile(params: {
provider: string;
primaryProvider: string;
authProfileId?: string;
authProfileIdSource?: "auto" | "user";
}): { authProfileId?: string; authProfileIdSource?: "auto" | "user" } {
const authProfileId =
params.provider === params.primaryProvider ? params.authProfileId : undefined;
return {
authProfileId,
authProfileIdSource: authProfileId ? params.authProfileIdSource : undefined,
};
}

View File

@@ -15,6 +15,7 @@ import { registerAgentRunContext } from "../../infra/agent-events.js";
import { defaultRuntime } from "../../runtime.js"; import { defaultRuntime } from "../../runtime.js";
import { stripHeartbeatToken } from "../heartbeat.js"; import { stripHeartbeatToken } from "../heartbeat.js";
import { isSilentReplyText, SILENT_REPLY_TOKEN } from "../tokens.js"; import { isSilentReplyText, SILENT_REPLY_TOKEN } from "../tokens.js";
import { resolveRunAuthProfile } from "./agent-runner-utils.js";
import { import {
applyReplyThreading, applyReplyThreading,
filterMessagingToolDuplicates, filterMessagingToolDuplicates,
@@ -135,8 +136,7 @@ export function createFollowupRunner(params: {
resolveAgentIdFromSessionKey(queued.run.sessionKey), resolveAgentIdFromSessionKey(queued.run.sessionKey),
), ),
run: (provider, model) => { run: (provider, model) => {
const authProfileId = const authProfile = resolveRunAuthProfile(queued.run, provider);
provider === queued.run.provider ? queued.run.authProfileId : undefined;
return runEmbeddedPiAgent({ return runEmbeddedPiAgent({
sessionId: queued.run.sessionId, sessionId: queued.run.sessionId,
sessionKey: queued.run.sessionKey, sessionKey: queued.run.sessionKey,
@@ -162,8 +162,7 @@ export function createFollowupRunner(params: {
enforceFinalTag: queued.run.enforceFinalTag, enforceFinalTag: queued.run.enforceFinalTag,
provider, provider,
model, model,
authProfileId, ...authProfile,
authProfileIdSource: authProfileId ? queued.run.authProfileIdSource : undefined,
thinkLevel: queued.run.thinkLevel, thinkLevel: queued.run.thinkLevel,
verboseLevel: queued.run.verboseLevel, verboseLevel: queued.run.verboseLevel,
reasoningLevel: queued.run.reasoningLevel, reasoningLevel: queued.run.reasoningLevel,