refactor(agents): split embedded runner model setup (#107646)

This commit is contained in:
Peter Steinberger
2026-07-14 09:32:39 -07:00
committed by GitHub
parent 7f36f49052
commit 4ea573edd2
4 changed files with 634 additions and 400 deletions
+79 -400
View File
@@ -35,7 +35,6 @@ import { formatErrorMessage, toErrorObject } from "../../infra/errors.js";
import { redactIdentifier } from "../../logging/redact-identifier.js";
import { buildAgentHookContextChannelFields } from "../../plugins/hook-agent-context.js";
import { getGlobalHookRunner } from "../../plugins/hook-runner-global.js";
import { resolveProviderAuthProfileId } from "../../plugins/provider-runtime.js";
import { looksLikeSecretSentinel, resolveSecretSentinel } from "../../secrets/sentinel.js";
import { createAgentHarnessTaskRuntimeScope } from "../../tasks/agent-harness-task-runtime-scope.js";
import { createTrajectoryRuntimeRecorder } from "../../trajectory/runtime.js";
@@ -59,7 +58,6 @@ import {
markAuthProfileFailure,
markAuthProfileSuccess,
} from "../auth-profiles.js";
import { resolveExternalCliAuthOverlayScopeFromSelection } from "../auth-profiles/external-cli-auth-selection.js";
import { listActiveProcessSessionReferences } from "../bash-process-references.js";
import { DEFAULT_MODEL, DEFAULT_PROVIDER } from "../defaults.js";
import {
@@ -94,31 +92,14 @@ import {
FailoverError,
resolveFailoverStatus,
} from "../failover-error.js";
import { ensureSelectedAgentHarnessPlugin } from "../harness/runtime-plugin.js";
import {
agentHarnessBuildsOpenClawTools,
selectAgentHarness,
selectAgentHarnessForPreparedModelProviders,
} from "../harness/selection.js";
import {
resolveAgentHarnessPreparedAuthSupport,
resolveAgentHarnessPreparedRouteSupport,
} from "../harness/support.js";
import { agentHarnessBuildsOpenClawTools } from "../harness/selection.js";
import { LiveSessionModelSwitchError } from "../live-model-switch-error.js";
import { shouldSwitchToLiveModel, clearLiveModelSwitchPending } from "../live-model-switch.js";
import {
applyAuthHeaderOverride,
applyLocalNoAuthHeaderOverride,
ensureAuthProfileStore,
ensureAuthProfileStoreWithoutExternalProfiles,
type ResolvedProviderAuth,
} from "../model-auth.js";
import { ensureOpenClawModelsJson } from "../models-config.js";
import {
OPENAI_PROVIDER_ID,
resolveContextConfigProviderForRuntime,
resolveSelectedOpenAIRuntimeProvider,
} from "../openai-routing.js";
import { hasOnlyAssistantReasoningContent } from "../replay-turn-classification.js";
import { runAgentCleanupStep } from "../run-cleanup-timeout.js";
import {
@@ -128,14 +109,11 @@ import {
import { createAgentRunDirectAbortError } from "../run-termination.js";
import { buildAgentRuntimePlan } from "../runtime-plan/build.js";
import {
createPreparedRuntimeModelMaterializer,
hasPreparedAuthAttemptModelMetadata,
providerUsesCredentialScopedModelMetadata,
resolveCredentialScopedAuthAttemptModelDecision,
} from "../runtime-plan/credential-scoped-model.js";
import {
canRunPreparedAgentRuntimeAuthAttempt,
prepareAgentRuntimeAuth,
type PreparedAgentRuntimeAuthAttempt,
} from "../runtime-plan/prepare-auth.js";
import type { AgentRuntimeAuthPlan } from "../runtime-plan/types.js";
@@ -168,7 +146,6 @@ import {
import { resolveEmbeddedRunFailureSignal } from "./failure-signal.js";
import { resolveGlobalLane, resolveSessionLane } from "./lanes.js";
import { log } from "./logger.js";
import { createEmptyAgentDiscoveryStores, resolveModelAsync } from "./model.js";
import {
createPostCompactionLoopGuard,
PostCompactionLoopPersistedError,
@@ -189,6 +166,7 @@ import {
createEmbeddedRunAuthController,
resolveEmbeddedAuthCooldownProbePolicy,
} from "./run/auth-controller.js";
import { prepareEmbeddedRunAuthPlan } from "./run/auth-plan.js";
import { resolveAuthProfileFailureReason } from "./run/auth-profile-failure-policy.js";
import { createScopedAuthProfileStore, resolveAttemptDispatchApiKey } from "./run/auth-store.js";
import { runEmbeddedAttemptWithBackend } from "./run/backend.js";
@@ -246,6 +224,12 @@ import {
EMBEDDED_RUN_LANE_TIMEOUT_GRACE_MS,
resolveEmbeddedRunLaneTimeoutMs,
} from "./run/lane-runtime.js";
import {
resolveEmbeddedRunEffectiveModel,
selectEmbeddedRunHarness,
selectEmbeddedRunHarnessForPreparedAttempts,
} from "./run/model-harness.js";
import { resolveEmbeddedRunModelSetup } from "./run/model-setup.js";
import type { RunEmbeddedAgentParams } from "./run/params.js";
import { buildEmbeddedRunPayloads } from "./run/payloads.js";
import { createEmbeddedRunProgressController } from "./run/progress-controller.js";
@@ -260,7 +244,6 @@ import {
resolveAttemptTrajectoryAttribution,
resolveInitialEmbeddedRunModel,
resolveInitialThinkLevel,
resolveRequestStreamTransportOverrides,
} from "./run/runtime-resolution.js";
import {
assertAgentHarnessRunAdmission,
@@ -269,13 +252,6 @@ import {
isNoRealConversationCompactionNoop,
resetNoRealConversationTokenSnapshot,
} from "./run/session-bootstrap.js";
import {
buildBeforeModelResolveAttachments,
createNativeModelOwnedRuntimeModel,
resolveEmbeddedRuntimeModelPolicy,
resolveHookModelSelection,
resolveNativeModelOwnedHarnessId,
} from "./run/setup.js";
import { resolveSkillWorkshopAttemptParams } from "./run/skill-workshop-attempt-params.js";
import {
isEmbeddedRunTerminalAbort,
@@ -553,180 +529,46 @@ async function runEmbeddedAgentInternal(
notifyExecutionPhase("runtime_plugins", { provider, model: modelId });
}
const hookSelection = await resolveHookModelSelection({
prompt: params.prompt,
attachments: buildBeforeModelResolveAttachments(params.images),
const modelSetup = await resolveEmbeddedRunModelSetup({
runParams: params,
provider,
modelId,
modelSelectionLocked: params.modelSelectionLocked,
agentDir,
workspaceDir: resolvedWorkspace,
globalLane,
hookRunner,
hookContext: hookCtx,
onHooksResolved: () => startupStages.mark("hooks"),
});
const modelSelectionChangedByHook =
hookSelection.provider !== provider || hookSelection.modelId !== modelId;
provider = hookSelection.provider;
modelId = hookSelection.modelId;
const requestedModelId = modelId;
const beforeAgentStartResult = hookSelection.beforeAgentStartResult;
const requestStreamTransportOverrides = resolveRequestStreamTransportOverrides(
params.streamParams,
);
startupStages.mark("hooks");
await ensureSelectedAgentHarnessPlugin({
provider,
modelId,
config: params.config,
agentId: params.agentId,
sessionKey: params.sessionKey,
agentHarnessId: params.agentHarnessId,
agentHarnessRuntimeOverride: params.agentHarnessRuntimeOverride,
requestTransportOverrides: requestStreamTransportOverrides,
workspaceDir: resolvedWorkspace,
});
let agentHarness = selectAgentHarness({
provider,
modelId,
...(requestStreamTransportOverrides
? {
modelProvider: {
requestTransportOverrides: requestStreamTransportOverrides,
},
}
: {}),
config: params.config,
agentId: params.agentId,
sessionKey: params.sessionKey,
agentHarnessId: params.agentHarnessId,
agentHarnessRuntimeOverride: params.agentHarnessRuntimeOverride,
});
let pluginHarnessOwnsTransport = agentHarness.id !== "openclaw";
const expectedHarnessArtifact = params.expectedAgentHarnessRuntimeArtifact;
if (expectedHarnessArtifact && expectedHarnessArtifact.harnessId !== agentHarness.id) {
throw new Error(
`Verified inference requires agent harness ${expectedHarnessArtifact.harnessId}, but ${agentHarness.id} was selected.`,
);
}
if (expectedHarnessArtifact && !agentHarness.runtimeArtifact) {
throw new Error(
`Agent harness ${agentHarness.id} cannot attest the verified inference runtime artifact.`,
);
}
const nativeModelOwnedHarnessId = resolveNativeModelOwnedHarnessId({
agentHarnessId: params.agentHarnessId,
modelSelectionLocked: params.modelSelectionLocked,
selectedHarnessId: agentHarness.id,
});
const nativeModelOwned = nativeModelOwnedHarnessId !== undefined;
const modelConfigProvider = provider;
let resolvedModelProvider = provider;
let firstModelResolution: Awaited<ReturnType<typeof resolveModelAsync>> | undefined;
let modelResolution: Awaited<ReturnType<typeof resolveModelAsync>> | undefined;
if (nativeModelOwned) {
modelResolution = {
model: createNativeModelOwnedRuntimeModel({ provider, modelId }),
...createEmptyAgentDiscoveryStores(),
};
} else {
const selectedRuntimeProvider = resolveSelectedOpenAIRuntimeProvider({
provider,
harnessRuntime: agentHarness.id,
agentHarnessId: agentHarness.id,
authProfileProvider: params.authProfileId?.split(":", 1)[0],
authProfileId: params.authProfileId,
config: params.config,
workspaceDir: resolvedWorkspace,
});
const modelResolutionProviders =
selectedRuntimeProvider !== provider ? [selectedRuntimeProvider, provider] : [provider];
for (const candidateProvider of modelResolutionProviders) {
const candidateResolution = await resolveModelAsync(
candidateProvider,
modelId,
agentDir,
params.config,
{
// Plugin dynamic model hooks can resolve explicit model refs without
// first generating OpenClaw models.json. This keeps one-shot model runs from
// blocking on unrelated provider discovery.
skipAgentDiscovery: true,
allowBundledStaticCatalogFallback: pluginHarnessOwnsTransport,
preferBundledStaticCatalogTransport: pluginHarnessOwnsTransport,
workspaceDir: resolvedWorkspace,
authProfileId: params.authProfileId,
},
);
firstModelResolution ??= candidateResolution;
if (candidateResolution.model) {
resolvedModelProvider = candidateProvider;
modelResolution = candidateResolution;
break;
}
}
if (!modelResolution && pluginHarnessOwnsTransport) {
modelResolution ??= firstModelResolution;
}
if (!modelResolution) {
await ensureOpenClawModelsJson(params.config, agentDir, {
workspaceDir: resolvedWorkspace,
});
for (const candidateProvider of modelResolutionProviders) {
const candidateResolution = await resolveModelAsync(
candidateProvider,
modelId,
agentDir,
params.config,
{
workspaceDir: resolvedWorkspace,
authProfileId: params.authProfileId,
// Enable bundled static catalog fallback so plugin-provided
// models that are not discoverable via agent model discovery
// can still be resolved from the static catalog.
allowBundledStaticCatalogFallback: true,
},
);
firstModelResolution ??= candidateResolution;
if (candidateResolution.model) {
resolvedModelProvider = candidateProvider;
modelResolution = candidateResolution;
break;
}
}
}
modelResolution ??= firstModelResolution;
}
if (!modelResolution) {
throw new FailoverError(`Unknown model: ${provider}/${modelId}`, {
reason: "model_not_found",
provider,
model: modelId,
sessionId: params.sessionId,
lane: globalLane,
});
}
provider = resolvedModelProvider;
const { model, error, authStorage, modelRegistry } = modelResolution;
if (!model) {
throw new FailoverError(error ?? `Unknown model: ${provider}/${modelId}`, {
reason: "model_not_found",
provider,
model: modelId,
sessionId: params.sessionId,
lane: globalLane,
});
}
provider = modelSetup.provider;
modelId = modelSetup.modelId;
const {
requestedModelId,
modelSelectionChangedByHook,
beforeAgentStartResult,
requestStreamTransportOverrides,
expectedHarnessArtifact,
nativeModelOwnedHarnessId,
nativeModelOwned,
modelConfigProvider,
model,
authStorage,
modelRegistry,
} = modelSetup;
let agentHarness = modelSetup.agentHarness;
let pluginHarnessOwnsTransport = modelSetup.pluginHarnessOwnsTransport;
let runtimeModel = model;
const resolveEffectiveModel = (candidate: typeof runtimeModel) =>
resolveEmbeddedRuntimeModelPolicy({
cfg: params.config,
resolveEmbeddedRunEffectiveModel({
runParams: params,
provider,
contextConfigProvider: resolveContextConfigProviderForRuntime({
provider: modelConfigProvider,
runtimeId: agentHarness.id,
config: params.config,
}),
modelConfigProvider,
modelId,
agentHarnessId: agentHarness.id,
runtimeModel: candidate,
nativeModelOwned,
requestStreamTransportOverrides,
nativeModelOwnedHarnessId,
});
const initialResolvedRuntimeModel = resolveEffectiveModel(runtimeModel);
let contextTokenBudget = initialResolvedRuntimeModel.contextTokenBudget;
@@ -745,82 +587,34 @@ async function runEmbeddedAgentInternal(
outerContextTokenMeta =
contextTokenBudget === undefined ? {} : { contextTokens: contextTokenBudget };
};
const buildHarnessModelProvider = (
candidate: typeof effectiveModel,
plan?: AgentRuntimeAuthPlan,
preparedAuthAttempt?: PreparedAgentRuntimeAuthAttempt,
) => {
const route = plan?.modelRoute;
const routeSupport = resolveAgentHarnessPreparedRouteSupport(plan);
const requestTransportOverrides =
requestStreamTransportOverrides ?? routeSupport.requestTransportOverrides;
return {
api: route?.api ?? candidate.api,
baseUrl: route?.baseUrl ?? candidate.baseUrl,
...(requestTransportOverrides ? { requestTransportOverrides } : {}),
...(routeSupport.runtimePolicy ? { runtimePolicy: routeSupport.runtimePolicy } : {}),
...(plan
? {
preparedAuth: resolveAgentHarnessPreparedAuthSupport({
plan,
...(preparedAuthAttempt?.kind === "profile" ||
preparedAuthAttempt?.kind === "direct"
? { source: preparedAuthAttempt.kind }
: {}),
}),
}
: {}),
};
};
const selectHarnessForModel = (
candidate: typeof effectiveModel,
plan?: AgentRuntimeAuthPlan,
preparedAuthAttempt?: PreparedAgentRuntimeAuthAttempt,
) => {
const selected = selectAgentHarness({
) =>
selectEmbeddedRunHarness({
runParams: params,
provider,
modelId,
modelProvider: buildHarnessModelProvider(candidate, plan, preparedAuthAttempt),
config: params.config,
agentId: params.agentId,
sessionKey: params.sessionKey,
agentHarnessId: params.agentHarnessId,
agentHarnessRuntimeOverride: params.agentHarnessRuntimeOverride,
model: candidate,
plan,
preparedAuthAttempt,
requestStreamTransportOverrides,
nativeModelOwnedHarnessId,
});
if (nativeModelOwnedHarnessId && selected.id !== nativeModelOwnedHarnessId) {
throw new Error(
`Prepared model route changed the session-pinned agent harness from "${nativeModelOwnedHarnessId}" to "${selected.id}".`,
);
}
return selected;
};
const selectHarnessForPreparedAttempts = (
candidate: typeof effectiveModel,
attempts: readonly PreparedAgentRuntimeAuthAttempt[],
) => {
const selected = selectAgentHarnessForPreparedModelProviders({
) =>
selectEmbeddedRunHarnessForPreparedAttempts({
runParams: params,
provider,
modelId,
modelProviders: attempts.map((attempt) => {
const route = attempt.plan.modelRoute;
const attemptModel = route
? { ...candidate, api: route.api, baseUrl: route.baseUrl }
: candidate;
return buildHarnessModelProvider(attemptModel, attempt.plan, attempt);
}),
config: params.config,
agentId: params.agentId,
sessionKey: params.sessionKey,
agentHarnessId: params.agentHarnessId,
agentHarnessRuntimeOverride: params.agentHarnessRuntimeOverride,
model: candidate,
attempts,
requestStreamTransportOverrides,
nativeModelOwnedHarnessId,
});
if (nativeModelOwnedHarnessId && selected.id !== nativeModelOwnedHarnessId) {
throw new Error(
`Prepared auth routes changed the session-pinned agent harness from "${nativeModelOwnedHarnessId}" to "${selected.id}".`,
);
}
return selected;
};
startupStages.mark("model-resolution");
notifyExecutionPhase("model_resolution", { provider, model: modelId });
@@ -831,154 +625,39 @@ async function runEmbeddedAgentInternal(
pluginHarnessOwnsTransport = agentHarness.id !== "openclaw";
const authStages = log.isEnabled("trace") ? createEmbeddedRunStageTracker() : undefined;
const usesOpenAIAuthRouting = provider === OPENAI_PROVIDER_ID;
const openClawNativeCodexResponsesNeedsAuthBootstrap =
!pluginHarnessOwnsTransport &&
provider === OPENAI_PROVIDER_ID &&
effectiveModel.api === "openai-chatgpt-responses";
let piExternalCliAuthScope = pluginHarnessOwnsTransport
? { ignoreAutoPreferredProfile: false }
: openClawNativeCodexResponsesNeedsAuthBootstrap
? {
providerIds: [OPENAI_PROVIDER_ID],
ignoreAutoPreferredProfile: false,
}
: resolveExternalCliAuthOverlayScopeFromSelection({
provider,
cfg: params.config,
agentId: params.agentId,
modelId,
workspaceDir: resolvedWorkspace,
userLockedAuthProfileId:
params.authProfileIdSource === "user" ? params.authProfileId : undefined,
});
let noExternalAuthStore: AuthProfileStore | undefined;
if (!pluginHarnessOwnsTransport && !piExternalCliAuthScope.providerIds) {
noExternalAuthStore = ensureAuthProfileStoreWithoutExternalProfiles(agentDir, {
allowKeychainPrompt: false,
});
piExternalCliAuthScope = resolveExternalCliAuthOverlayScopeFromSelection({
provider,
cfg: params.config,
agentId: params.agentId,
modelId,
workspaceDir: resolvedWorkspace,
store: noExternalAuthStore,
userLockedAuthProfileId:
params.authProfileIdSource === "user" ? params.authProfileId : undefined,
});
}
authStages?.mark("scope");
const attemptAuthProfileStore = usesOpenAIAuthRouting
? ensureAuthProfileStore(agentDir, {
externalCliProviderIds: [OPENAI_PROVIDER_ID],
allowKeychainPrompt: false,
})
: pluginHarnessOwnsTransport
? ensureAuthProfileStoreWithoutExternalProfiles(agentDir, {
allowKeychainPrompt: false,
})
: piExternalCliAuthScope.providerIds
? ensureAuthProfileStore(agentDir, {
externalCliProviderIds: piExternalCliAuthScope.providerIds,
allowKeychainPrompt: false,
})
: (noExternalAuthStore ??
ensureAuthProfileStoreWithoutExternalProfiles(agentDir, {
allowKeychainPrompt: false,
}));
authStages?.mark("store");
const requestedProfileId = params.authProfileId?.trim() || undefined;
const lockedProfileId =
params.authProfileIdSource === "user" ? requestedProfileId : undefined;
const preferredProfileId =
piExternalCliAuthScope.ignoreAutoPreferredProfile && !lockedProfileId
? undefined
: requestedProfileId;
const createAuthPreparation = () =>
prepareAgentRuntimeAuth({
provider,
modelId,
modelApi: model.api,
modelBaseUrl: model.baseUrl,
requestTransportOverrides: requestStreamTransportOverrides,
config: params.config,
env: process.env,
agentDir,
workspaceDir: resolvedWorkspace,
authProfileStore: attemptAuthProfileStore,
sessionAuthProfileId: preferredProfileId,
sessionAuthProfileSource: params.authProfileIdSource,
harnessId: agentHarness.id,
harnessRuntime: agentHarness.id,
harnessAuthBootstrap: agentHarness.authBootstrap,
allowHarnessAuthProfileForwarding: true,
allowTransientCooldownProbe: params.allowTransientCooldownProbe === true,
resolveProviderPreferredProfileId: (context) =>
resolveProviderAuthProfileId({
provider,
config: params.config,
workspaceDir: resolvedWorkspace,
env: process.env,
context,
}),
});
const providerUsesProfileScopedModelMetadata = providerUsesCredentialScopedModelMetadata({
const preparedAuthPlan = await prepareEmbeddedRunAuthPlan({
runParams: params,
provider,
modelId,
config: params.config,
model,
agentDir,
workspaceDir: resolvedWorkspace,
requestStreamTransportOverrides,
nativeModelOwned,
authStorage,
modelRegistry,
getAgentHarness: () => agentHarness,
setAgentHarness: (nextHarness) => {
agentHarness = nextHarness;
pluginHarnessOwnsTransport = agentHarness.id !== "openclaw";
},
getRuntimeModel: () => runtimeModel,
getEffectiveModel: () => effectiveModel,
applyResolvedRuntimeModel,
selectHarnessForPreparedAttempts,
markStage: (stage) => authStages?.mark(stage),
});
const { materialize: materializeAuthPlan, materializeUncached: materializeAuthPlanUncached } =
createPreparedRuntimeModelMaterializer({
provider,
modelId,
config: params.config,
getModel: () => runtimeModel,
nativeModelOwned,
requestedProfileId: params.authProfileId,
providerUsesProfileScopedModelMetadata,
resolveModel: ({ config, authProfileId, authProfileMode }) =>
resolveModelAsync(provider, modelId, agentDir, config, {
authStorage,
modelRegistry,
skipAgentDiscovery: true,
allowBundledStaticCatalogFallback: true,
preferBundledStaticCatalogTransport: true,
workspaceDir: resolvedWorkspace,
authProfileId,
authProfileMode,
}),
});
let resolvedAuthPreparation = createAuthPreparation();
let preparedAuthAttempts = resolvedAuthPreparation.attempts;
let activePreparedAuthPlan = resolvedAuthPreparation.plan;
applyResolvedRuntimeModel(await materializeAuthPlan(activePreparedAuthPlan));
authStages?.mark("prepare-plan");
const finalizedHarness = selectHarnessForPreparedAttempts(
effectiveModel,
const {
usesOpenAIAuthRouting,
attemptAuthProfileStore,
lockedProfileId,
preferredProfileId,
providerUsesProfileScopedModelMetadata,
materializeAuthPlan,
materializeAuthPlanUncached,
preparedAuthAttempts,
);
if (finalizedHarness.id !== agentHarness.id) {
agentHarness = finalizedHarness;
pluginHarnessOwnsTransport = agentHarness.id !== "openclaw";
resolvedAuthPreparation = createAuthPreparation();
preparedAuthAttempts = resolvedAuthPreparation.attempts;
activePreparedAuthPlan = resolvedAuthPreparation.plan;
applyResolvedRuntimeModel(await materializeAuthPlan(activePreparedAuthPlan));
const confirmedHarness = selectHarnessForPreparedAttempts(
effectiveModel,
preparedAuthAttempts,
);
if (confirmedHarness.id !== agentHarness.id) {
throw new Error(
`Prepared auth route did not converge on one agent harness for ${provider}/${modelId}.`,
);
}
}
authStages?.mark("harness");
} = preparedAuthPlan;
let { activePreparedAuthPlan } = preparedAuthPlan;
// A selected plugin harness owns context pressure with its native transcript,
// even if it cannot expose manual compaction. Generic recovery is OpenClaw-only.
const genericCompactionRecoveryAllowed = !pluginHarnessOwnsTransport;
@@ -0,0 +1,212 @@
import { resolveProviderAuthProfileId } from "../../../plugins/provider-runtime.js";
import type { AuthProfileStore } from "../../auth-profiles.js";
import { resolveExternalCliAuthOverlayScopeFromSelection } from "../../auth-profiles/external-cli-auth-selection.js";
import type { AgentHarness } from "../../harness/types.js";
import {
ensureAuthProfileStore,
ensureAuthProfileStoreWithoutExternalProfiles,
} from "../../model-auth.js";
import { OPENAI_PROVIDER_ID } from "../../openai-routing.js";
import {
createPreparedRuntimeModelMaterializer,
providerUsesCredentialScopedModelMetadata,
} from "../../runtime-plan/credential-scoped-model.js";
import {
prepareAgentRuntimeAuth,
type PreparedAgentRuntimeAuthAttempt,
} from "../../runtime-plan/prepare-auth.js";
import { resolveModelAsync } from "../model.js";
import type { RunEmbeddedAgentParams } from "./params.js";
type ModelResolution = Awaited<ReturnType<typeof resolveModelAsync>>;
type RuntimeModel = NonNullable<ModelResolution["model"]>;
export async function prepareEmbeddedRunAuthPlan(params: {
runParams: RunEmbeddedAgentParams;
provider: string;
modelId: string;
model: RuntimeModel;
agentDir: string;
workspaceDir: string;
requestStreamTransportOverrides?: "present";
nativeModelOwned: boolean;
authStorage: ModelResolution["authStorage"];
modelRegistry: ModelResolution["modelRegistry"];
getAgentHarness: () => AgentHarness;
setAgentHarness: (harness: AgentHarness) => void;
getRuntimeModel: () => RuntimeModel;
getEffectiveModel: () => RuntimeModel;
applyResolvedRuntimeModel: (model: RuntimeModel) => void;
selectHarnessForPreparedAttempts: (
model: RuntimeModel,
attempts: readonly PreparedAgentRuntimeAuthAttempt[],
) => AgentHarness;
markStage?: (stage: string) => void;
}) {
const runParams = params.runParams;
const usesOpenAIAuthRouting = params.provider === OPENAI_PROVIDER_ID;
const initialHarness = params.getAgentHarness();
const initialPluginHarnessOwnsTransport = initialHarness.id !== "openclaw";
const openClawNativeCodexResponsesNeedsAuthBootstrap =
!initialPluginHarnessOwnsTransport &&
usesOpenAIAuthRouting &&
params.getEffectiveModel().api === "openai-chatgpt-responses";
let externalCliAuthScope = initialPluginHarnessOwnsTransport
? { ignoreAutoPreferredProfile: false }
: openClawNativeCodexResponsesNeedsAuthBootstrap
? {
providerIds: [OPENAI_PROVIDER_ID],
ignoreAutoPreferredProfile: false,
}
: resolveExternalCliAuthOverlayScopeFromSelection({
provider: params.provider,
cfg: runParams.config,
agentId: runParams.agentId,
modelId: params.modelId,
workspaceDir: params.workspaceDir,
userLockedAuthProfileId:
runParams.authProfileIdSource === "user" ? runParams.authProfileId : undefined,
});
let noExternalAuthStore: AuthProfileStore | undefined;
if (!initialPluginHarnessOwnsTransport && !externalCliAuthScope.providerIds) {
noExternalAuthStore = ensureAuthProfileStoreWithoutExternalProfiles(params.agentDir, {
allowKeychainPrompt: false,
});
externalCliAuthScope = resolveExternalCliAuthOverlayScopeFromSelection({
provider: params.provider,
cfg: runParams.config,
agentId: runParams.agentId,
modelId: params.modelId,
workspaceDir: params.workspaceDir,
store: noExternalAuthStore,
userLockedAuthProfileId:
runParams.authProfileIdSource === "user" ? runParams.authProfileId : undefined,
});
}
params.markStage?.("scope");
const attemptAuthProfileStore = usesOpenAIAuthRouting
? ensureAuthProfileStore(params.agentDir, {
externalCliProviderIds: [OPENAI_PROVIDER_ID],
allowKeychainPrompt: false,
})
: initialPluginHarnessOwnsTransport
? ensureAuthProfileStoreWithoutExternalProfiles(params.agentDir, {
allowKeychainPrompt: false,
})
: externalCliAuthScope.providerIds
? ensureAuthProfileStore(params.agentDir, {
externalCliProviderIds: externalCliAuthScope.providerIds,
allowKeychainPrompt: false,
})
: (noExternalAuthStore ??
ensureAuthProfileStoreWithoutExternalProfiles(params.agentDir, {
allowKeychainPrompt: false,
}));
params.markStage?.("store");
const requestedProfileId = runParams.authProfileId?.trim() || undefined;
const lockedProfileId = runParams.authProfileIdSource === "user" ? requestedProfileId : undefined;
const preferredProfileId =
externalCliAuthScope.ignoreAutoPreferredProfile && !lockedProfileId
? undefined
: requestedProfileId;
const createAuthPreparation = () => {
const harness = params.getAgentHarness();
return prepareAgentRuntimeAuth({
provider: params.provider,
modelId: params.modelId,
modelApi: params.model.api,
modelBaseUrl: params.model.baseUrl,
requestTransportOverrides: params.requestStreamTransportOverrides,
config: runParams.config,
env: process.env,
agentDir: params.agentDir,
workspaceDir: params.workspaceDir,
authProfileStore: attemptAuthProfileStore,
sessionAuthProfileId: preferredProfileId,
sessionAuthProfileSource: runParams.authProfileIdSource,
harnessId: harness.id,
harnessRuntime: harness.id,
harnessAuthBootstrap: harness.authBootstrap,
allowHarnessAuthProfileForwarding: true,
allowTransientCooldownProbe: runParams.allowTransientCooldownProbe === true,
resolveProviderPreferredProfileId: (context) =>
resolveProviderAuthProfileId({
provider: params.provider,
config: runParams.config,
workspaceDir: params.workspaceDir,
env: process.env,
context,
}),
});
};
const providerUsesProfileScopedModelMetadata = providerUsesCredentialScopedModelMetadata({
provider: params.provider,
modelId: params.modelId,
config: runParams.config,
agentDir: params.agentDir,
workspaceDir: params.workspaceDir,
});
const { materialize: materializeAuthPlan, materializeUncached: materializeAuthPlanUncached } =
createPreparedRuntimeModelMaterializer({
provider: params.provider,
modelId: params.modelId,
config: runParams.config,
getModel: params.getRuntimeModel,
nativeModelOwned: params.nativeModelOwned,
requestedProfileId: runParams.authProfileId,
providerUsesProfileScopedModelMetadata,
resolveModel: ({ config, authProfileId, authProfileMode }) =>
resolveModelAsync(params.provider, params.modelId, params.agentDir, config, {
authStorage: params.authStorage,
modelRegistry: params.modelRegistry,
skipAgentDiscovery: true,
allowBundledStaticCatalogFallback: true,
preferBundledStaticCatalogTransport: true,
workspaceDir: params.workspaceDir,
authProfileId,
authProfileMode,
}),
});
let resolvedAuthPreparation = createAuthPreparation();
let preparedAuthAttempts = resolvedAuthPreparation.attempts;
let activePreparedAuthPlan = resolvedAuthPreparation.plan;
params.applyResolvedRuntimeModel(await materializeAuthPlan(activePreparedAuthPlan));
params.markStage?.("prepare-plan");
const finalizedHarness = params.selectHarnessForPreparedAttempts(
params.getEffectiveModel(),
preparedAuthAttempts,
);
if (finalizedHarness.id !== params.getAgentHarness().id) {
params.setAgentHarness(finalizedHarness);
resolvedAuthPreparation = createAuthPreparation();
preparedAuthAttempts = resolvedAuthPreparation.attempts;
activePreparedAuthPlan = resolvedAuthPreparation.plan;
params.applyResolvedRuntimeModel(await materializeAuthPlan(activePreparedAuthPlan));
const confirmedHarness = params.selectHarnessForPreparedAttempts(
params.getEffectiveModel(),
preparedAuthAttempts,
);
if (confirmedHarness.id !== params.getAgentHarness().id) {
throw new Error(
`Prepared auth route did not converge on one agent harness for ${params.provider}/${params.modelId}.`,
);
}
}
params.markStage?.("harness");
return {
usesOpenAIAuthRouting,
attemptAuthProfileStore,
lockedProfileId,
preferredProfileId,
providerUsesProfileScopedModelMetadata,
materializeAuthPlan,
materializeAuthPlanUncached,
preparedAuthAttempts,
activePreparedAuthPlan,
};
}
@@ -0,0 +1,140 @@
import type { Model } from "../../../llm/types.js";
import {
selectAgentHarness,
selectAgentHarnessForPreparedModelProviders,
type AgentHarnessPreparedModelProvider,
} from "../../harness/selection.js";
import {
resolveAgentHarnessPreparedAuthSupport,
resolveAgentHarnessPreparedRouteSupport,
} from "../../harness/support.js";
import type { AgentHarness } from "../../harness/types.js";
import { resolveContextConfigProviderForRuntime } from "../../openai-routing.js";
import type { PreparedAgentRuntimeAuthAttempt } from "../../runtime-plan/prepare-auth.js";
import type { AgentRuntimeAuthPlan } from "../../runtime-plan/types.js";
import type { RunEmbeddedAgentParams } from "./params.js";
import { resolveEmbeddedRuntimeModelPolicy } from "./setup.js";
type HarnessSelectionContext = {
runParams: RunEmbeddedAgentParams;
provider: string;
modelId: string;
requestStreamTransportOverrides?: "present";
nativeModelOwnedHarnessId?: string;
};
export function resolveEmbeddedRunEffectiveModel(
params: HarnessSelectionContext & {
modelConfigProvider: string;
agentHarnessId: string;
runtimeModel: Model;
nativeModelOwned: boolean;
},
) {
return resolveEmbeddedRuntimeModelPolicy({
cfg: params.runParams.config,
provider: params.provider,
contextConfigProvider: resolveContextConfigProviderForRuntime({
provider: params.modelConfigProvider,
runtimeId: params.agentHarnessId,
config: params.runParams.config,
}),
modelId: params.modelId,
runtimeModel: params.runtimeModel,
nativeModelOwned: params.nativeModelOwned,
});
}
function buildHarnessModelProvider(
params: HarnessSelectionContext & {
model: Model;
plan?: AgentRuntimeAuthPlan;
preparedAuthAttempt?: PreparedAgentRuntimeAuthAttempt;
},
): AgentHarnessPreparedModelProvider {
const route = params.plan?.modelRoute;
const routeSupport = resolveAgentHarnessPreparedRouteSupport(params.plan);
const requestTransportOverrides =
params.requestStreamTransportOverrides ?? routeSupport.requestTransportOverrides;
return {
api: route?.api ?? params.model.api,
baseUrl: route?.baseUrl ?? params.model.baseUrl,
...(requestTransportOverrides ? { requestTransportOverrides } : {}),
...(routeSupport.runtimePolicy ? { runtimePolicy: routeSupport.runtimePolicy } : {}),
...(params.plan
? {
preparedAuth: resolveAgentHarnessPreparedAuthSupport({
plan: params.plan,
...(params.preparedAuthAttempt?.kind === "profile" ||
params.preparedAuthAttempt?.kind === "direct"
? { source: params.preparedAuthAttempt.kind }
: {}),
}),
}
: {}),
};
}
function assertPinnedHarness(
nativeModelOwnedHarnessId: string | undefined,
selected: AgentHarness,
subject: string,
): void {
if (nativeModelOwnedHarnessId && selected.id !== nativeModelOwnedHarnessId) {
throw new Error(
`${subject} changed the session-pinned agent harness from "${nativeModelOwnedHarnessId}" to "${selected.id}".`,
);
}
}
export function selectEmbeddedRunHarness(
params: HarnessSelectionContext & {
model: Model;
plan?: AgentRuntimeAuthPlan;
preparedAuthAttempt?: PreparedAgentRuntimeAuthAttempt;
},
): AgentHarness {
const selected = selectAgentHarness({
provider: params.provider,
modelId: params.modelId,
modelProvider: buildHarnessModelProvider(params),
config: params.runParams.config,
agentId: params.runParams.agentId,
sessionKey: params.runParams.sessionKey,
agentHarnessId: params.runParams.agentHarnessId,
agentHarnessRuntimeOverride: params.runParams.agentHarnessRuntimeOverride,
});
assertPinnedHarness(params.nativeModelOwnedHarnessId, selected, "Prepared model route");
return selected;
}
export function selectEmbeddedRunHarnessForPreparedAttempts(
params: HarnessSelectionContext & {
model: Model;
attempts: readonly PreparedAgentRuntimeAuthAttempt[];
},
): AgentHarness {
const selected = selectAgentHarnessForPreparedModelProviders({
provider: params.provider,
modelId: params.modelId,
modelProviders: params.attempts.map((attempt) => {
const route = attempt.plan.modelRoute;
const model = route
? { ...params.model, api: route.api, baseUrl: route.baseUrl }
: params.model;
return buildHarnessModelProvider({
...params,
model,
plan: attempt.plan,
preparedAuthAttempt: attempt,
});
}),
config: params.runParams.config,
agentId: params.runParams.agentId,
sessionKey: params.runParams.sessionKey,
agentHarnessId: params.runParams.agentHarnessId,
agentHarnessRuntimeOverride: params.runParams.agentHarnessRuntimeOverride,
});
assertPinnedHarness(params.nativeModelOwnedHarnessId, selected, "Prepared auth routes");
return selected;
}
@@ -0,0 +1,203 @@
import { FailoverError } from "../../failover-error.js";
import { ensureSelectedAgentHarnessPlugin } from "../../harness/runtime-plugin.js";
import { selectAgentHarness } from "../../harness/selection.js";
import { ensureOpenClawModelsJson } from "../../models-config.js";
import { resolveSelectedOpenAIRuntimeProvider } from "../../openai-routing.js";
import { createEmptyAgentDiscoveryStores, resolveModelAsync } from "../model.js";
import type { RunEmbeddedAgentParams } from "./params.js";
import { resolveRequestStreamTransportOverrides } from "./runtime-resolution.js";
import {
buildBeforeModelResolveAttachments,
createNativeModelOwnedRuntimeModel,
resolveHookModelSelection,
resolveNativeModelOwnedHarnessId,
} from "./setup.js";
export async function resolveEmbeddedRunModelSetup(params: {
runParams: RunEmbeddedAgentParams;
provider: string;
modelId: string;
agentDir: string;
workspaceDir: string;
globalLane: string;
hookRunner: Parameters<typeof resolveHookModelSelection>[0]["hookRunner"];
hookContext: Parameters<typeof resolveHookModelSelection>[0]["hookContext"];
onHooksResolved: () => void;
}) {
const runParams = params.runParams;
const hookSelection = await resolveHookModelSelection({
prompt: runParams.prompt,
attachments: buildBeforeModelResolveAttachments(runParams.images),
provider: params.provider,
modelId: params.modelId,
modelSelectionLocked: runParams.modelSelectionLocked,
hookRunner: params.hookRunner,
hookContext: params.hookContext,
});
const modelSelectionChangedByHook =
hookSelection.provider !== params.provider || hookSelection.modelId !== params.modelId;
let provider = hookSelection.provider;
const modelId = hookSelection.modelId;
const requestedModelId = modelId;
const requestStreamTransportOverrides = resolveRequestStreamTransportOverrides(
runParams.streamParams,
);
params.onHooksResolved();
await ensureSelectedAgentHarnessPlugin({
provider,
modelId,
config: runParams.config,
agentId: runParams.agentId,
sessionKey: runParams.sessionKey,
agentHarnessId: runParams.agentHarnessId,
agentHarnessRuntimeOverride: runParams.agentHarnessRuntimeOverride,
requestTransportOverrides: requestStreamTransportOverrides,
workspaceDir: params.workspaceDir,
});
const agentHarness = selectAgentHarness({
provider,
modelId,
...(requestStreamTransportOverrides
? {
modelProvider: {
requestTransportOverrides: requestStreamTransportOverrides,
},
}
: {}),
config: runParams.config,
agentId: runParams.agentId,
sessionKey: runParams.sessionKey,
agentHarnessId: runParams.agentHarnessId,
agentHarnessRuntimeOverride: runParams.agentHarnessRuntimeOverride,
});
const pluginHarnessOwnsTransport = agentHarness.id !== "openclaw";
const expectedHarnessArtifact = runParams.expectedAgentHarnessRuntimeArtifact;
if (expectedHarnessArtifact && expectedHarnessArtifact.harnessId !== agentHarness.id) {
throw new Error(
`Verified inference requires agent harness ${expectedHarnessArtifact.harnessId}, but ${agentHarness.id} was selected.`,
);
}
if (expectedHarnessArtifact && !agentHarness.runtimeArtifact) {
throw new Error(
`Agent harness ${agentHarness.id} cannot attest the verified inference runtime artifact.`,
);
}
const nativeModelOwnedHarnessId = resolveNativeModelOwnedHarnessId({
agentHarnessId: runParams.agentHarnessId,
modelSelectionLocked: runParams.modelSelectionLocked,
selectedHarnessId: agentHarness.id,
});
const nativeModelOwned = nativeModelOwnedHarnessId !== undefined;
const modelConfigProvider = provider;
let resolvedModelProvider = provider;
let firstModelResolution: Awaited<ReturnType<typeof resolveModelAsync>> | undefined;
let modelResolution: Awaited<ReturnType<typeof resolveModelAsync>> | undefined;
if (nativeModelOwned) {
modelResolution = {
model: createNativeModelOwnedRuntimeModel({ provider, modelId }),
...createEmptyAgentDiscoveryStores(),
};
} else {
const selectedRuntimeProvider = resolveSelectedOpenAIRuntimeProvider({
provider,
harnessRuntime: agentHarness.id,
agentHarnessId: agentHarness.id,
authProfileProvider: runParams.authProfileId?.split(":", 1)[0],
authProfileId: runParams.authProfileId,
config: runParams.config,
workspaceDir: params.workspaceDir,
});
const modelResolutionProviders =
selectedRuntimeProvider !== provider ? [selectedRuntimeProvider, provider] : [provider];
for (const candidateProvider of modelResolutionProviders) {
const candidateResolution = await resolveModelAsync(
candidateProvider,
modelId,
params.agentDir,
runParams.config,
{
// Dynamic hooks can resolve an explicit model without generating models.json first.
skipAgentDiscovery: true,
allowBundledStaticCatalogFallback: pluginHarnessOwnsTransport,
preferBundledStaticCatalogTransport: pluginHarnessOwnsTransport,
workspaceDir: params.workspaceDir,
authProfileId: runParams.authProfileId,
},
);
firstModelResolution ??= candidateResolution;
if (candidateResolution.model) {
resolvedModelProvider = candidateProvider;
modelResolution = candidateResolution;
break;
}
}
if (!modelResolution && pluginHarnessOwnsTransport) {
modelResolution = firstModelResolution;
}
if (!modelResolution) {
await ensureOpenClawModelsJson(runParams.config, params.agentDir, {
workspaceDir: params.workspaceDir,
});
for (const candidateProvider of modelResolutionProviders) {
const candidateResolution = await resolveModelAsync(
candidateProvider,
modelId,
params.agentDir,
runParams.config,
{
workspaceDir: params.workspaceDir,
authProfileId: runParams.authProfileId,
allowBundledStaticCatalogFallback: true,
},
);
firstModelResolution ??= candidateResolution;
if (candidateResolution.model) {
resolvedModelProvider = candidateProvider;
modelResolution = candidateResolution;
break;
}
}
}
modelResolution ??= firstModelResolution;
}
if (!modelResolution) {
throw new FailoverError(`Unknown model: ${provider}/${modelId}`, {
reason: "model_not_found",
provider,
model: modelId,
sessionId: runParams.sessionId,
lane: params.globalLane,
});
}
provider = resolvedModelProvider;
const { model, error, authStorage, modelRegistry } = modelResolution;
if (!model) {
throw new FailoverError(error ?? `Unknown model: ${provider}/${modelId}`, {
reason: "model_not_found",
provider,
model: modelId,
sessionId: runParams.sessionId,
lane: params.globalLane,
});
}
return {
provider,
modelId,
requestedModelId,
modelSelectionChangedByHook,
beforeAgentStartResult: hookSelection.beforeAgentStartResult,
requestStreamTransportOverrides,
expectedHarnessArtifact,
agentHarness,
pluginHarnessOwnsTransport,
nativeModelOwnedHarnessId,
nativeModelOwned,
modelConfigProvider,
model,
authStorage,
modelRegistry,
};
}