- test(FN-2617): stabilize workflow remediation timeout under full suite - test(FN-2617): complete Step 5 — add openclaw runtime resolution coverage - feat(FN-2617): complete Step 4 — route step sessions through runtime resolution - fix(FN-2617): thread runtimeHint through merger rebase push flow - feat(FN-2617): complete Step 3 — wire runtimeHint across engine subsystems - feat(FN-2617): complete Step 2 — thread runtimeHint in executor paths - feat(FN-2617): complete Step 1 — add runtimeHint extraction helper
130 lines
4.3 KiB
TypeScript
130 lines
4.3 KiB
TypeScript
/**
|
|
* Helper functions for creating agent sessions with runtime resolution.
|
|
*
|
|
* These helpers wrap the runtime resolution pattern so that subsystems
|
|
* don't need to duplicate the resolution logic. They use the resolver
|
|
* to select the appropriate runtime and then delegate to it for session
|
|
* creation and prompting.
|
|
*/
|
|
|
|
import type { AgentRuntimeOptions } from "./agent-runtime.js";
|
|
import type { PluginRunner } from "./plugin-runner.js";
|
|
import type { AgentSession } from "@mariozechner/pi-coding-agent";
|
|
import { resolveRuntime, buildRuntimeResolutionContext, type SessionPurpose } from "./runtime-resolution.js";
|
|
import { createLogger } from "./logger.js";
|
|
|
|
/** Logger for agent session helpers */
|
|
const sessionLog = createLogger("agent-session");
|
|
|
|
/**
|
|
* Options for creating an agent session with runtime resolution.
|
|
*/
|
|
export interface ResolvedSessionOptions extends AgentRuntimeOptions {
|
|
/** Session purpose for runtime selection */
|
|
sessionPurpose: SessionPurpose;
|
|
/** Plugin runner for runtime lookup. When provided, enables plugin runtime selection. */
|
|
pluginRunner?: PluginRunner;
|
|
/** Optional runtime hint from task/agent configuration */
|
|
runtimeHint?: string;
|
|
}
|
|
|
|
/**
|
|
* Result of creating an agent session with runtime resolution.
|
|
*/
|
|
export interface ResolvedSessionResult {
|
|
/** The created agent session */
|
|
session: AgentSession;
|
|
/** Path to the persisted session file (undefined for in-memory sessions) */
|
|
sessionFile?: string;
|
|
/** The runtime ID that was used */
|
|
runtimeId: string;
|
|
/** Whether the runtime was explicitly configured */
|
|
wasConfigured: boolean;
|
|
}
|
|
|
|
/**
|
|
* Extract runtime hint from untyped runtimeConfig payload.
|
|
*
|
|
* @param runtimeConfig - Agent/task runtime configuration
|
|
* @returns normalized runtime hint or undefined when missing/invalid
|
|
*/
|
|
export function extractRuntimeHint(
|
|
runtimeConfig: Record<string, unknown> | undefined,
|
|
): string | undefined {
|
|
const hint = runtimeConfig?.runtimeHint;
|
|
if (typeof hint !== "string") {
|
|
return undefined;
|
|
}
|
|
|
|
const normalizedHint = hint.trim();
|
|
return normalizedHint.length > 0 ? normalizedHint : undefined;
|
|
}
|
|
|
|
/**
|
|
* Create an agent session using runtime resolution.
|
|
*
|
|
* This function:
|
|
* 1. Resolves the appropriate runtime based on sessionPurpose, runtimeHint, and pluginRunner
|
|
* 2. Creates the session using the resolved runtime
|
|
* 3. Returns the session along with metadata about which runtime was used
|
|
*
|
|
* @param options - Session creation options including purpose and runtime configuration
|
|
* @returns Promise resolving to the session result with runtime metadata
|
|
*/
|
|
export async function createResolvedAgentSession(
|
|
options: ResolvedSessionOptions,
|
|
): Promise<ResolvedSessionResult> {
|
|
const { sessionPurpose, pluginRunner, runtimeHint, ...runtimeOptions } = options;
|
|
|
|
// Build the resolution context
|
|
const context = buildRuntimeResolutionContext(sessionPurpose, pluginRunner, runtimeHint);
|
|
|
|
// Resolve the runtime
|
|
const resolved = await resolveRuntime(context);
|
|
|
|
sessionLog.log(
|
|
`[${sessionPurpose}] Using runtime "${resolved.runtimeId}" (configured=${resolved.wasConfigured})`,
|
|
);
|
|
|
|
// Create the session using the resolved runtime
|
|
const result = await resolved.runtime.createSession(runtimeOptions);
|
|
|
|
return {
|
|
session: result.session,
|
|
sessionFile: result.sessionFile,
|
|
runtimeId: resolved.runtimeId,
|
|
wasConfigured: resolved.wasConfigured,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Prompt an agent session with automatic retry and compaction.
|
|
*
|
|
* This is a convenience wrapper that delegates to the runtime's promptWithFallback.
|
|
*
|
|
* @param session - The session to prompt
|
|
* @param prompt - The prompt text
|
|
* @param options - Optional prompt options (e.g., images)
|
|
*/
|
|
export async function promptWithAutoRetry(
|
|
session: AgentSession,
|
|
prompt: string,
|
|
options?: unknown,
|
|
): Promise<void> {
|
|
// Dynamic import to get the default runtime's promptWithFallback
|
|
// This works because the default runtime delegates to the existing implementation
|
|
const { promptWithFallback: pwf } = await import("./pi.js");
|
|
return pwf(session, prompt, options);
|
|
}
|
|
|
|
/**
|
|
* Get a human-readable model description from a session.
|
|
*
|
|
* @param session - The session to describe
|
|
* @returns Model description string
|
|
*/
|
|
export async function describeAgentModel(session: AgentSession): Promise<string> {
|
|
const { describeModel: dm } = await import("./pi.js");
|
|
return dm(session);
|
|
}
|