mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-18 15:14:45 +00:00
Fix OpenAI Codex runtime provider routing (#82864)
* fix: route Codex OpenAI runtime through Codex provider * docs: add Codex routing evidence collection * fix(agents): bootstrap OAuth credentials for Codex harness with openai/* model refs When a plugin harness (e.g. Codex) owns its transport but the runtime plan resolved to openai-codex via agentRuntime.id: codex, the auth profile store was left empty because pluginHarnessOwnsTransport short- circuited initializeAuthProfile(). This caused 'No API key found for openai-codex' at runtime even though the OAuth profile existed in OpenClaw's store. - Add pluginHarnessNeedsOpenClawAuthBootstrap flag when harness owns transport but the provider is openai-codex and the API is openai-codex- responses - Populate authStore and attemptAuthProfileStore from OpenClaw's profile store in this case - Run initializeAuthProfile() to forward the OAuth token into the harness - Update overflow-compaction tests to expect 'openai-codex' provider and add dedicated test for OAuth bootstrap path * fix(agents): refresh Codex OAuth credentials on profile rotation --------- Co-authored-by: PsiClawOps <267826480+PsiClawOps@users.noreply.github.com> Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
@@ -658,6 +658,36 @@ installed and enabled. If you need strict proof while testing, set provider or
|
||||
model `agentRuntime.id: "codex"`. A forced Codex runtime fails instead of
|
||||
falling back to PI.
|
||||
|
||||
**OpenAI Codex runtime falls back to the API-key path:** collect a redacted
|
||||
gateway excerpt that shows the model, runtime, selected provider, and failure.
|
||||
Ask affected collaborators to run this read-only command on their OpenClaw host:
|
||||
|
||||
```bash
|
||||
(
|
||||
pattern='openai/gpt-5\.[45]|agentRuntime(\.id)?|harnessRuntime|Runtime: OpenAI Codex|openai-codex|resolveSelectedOpenAIPiRuntimeProvider|candidateProvider[": ]+openai|status[": ]+401|Incorrect API key|No API key|api-key path|API-key path|OAuth'
|
||||
|
||||
if ls /tmp/openclaw/openclaw-*.log >/dev/null 2>&1; then
|
||||
grep -E -i -n "$pattern" /tmp/openclaw/openclaw-*.log 2>/dev/null || true
|
||||
else
|
||||
journalctl --user -u openclaw-gateway --since today --no-pager 2>/dev/null \
|
||||
| grep -E -i "$pattern" || true
|
||||
fi
|
||||
) | sed -E \
|
||||
-e 's/(Authorization: Bearer )[A-Za-z0-9._~+\/-]+/\1[REDACTED]/Ig' \
|
||||
-e 's/(Bearer )[A-Za-z0-9._~+\/-]+/\1[REDACTED]/Ig' \
|
||||
-e 's/(api[_ -]?key[=: ]+)[^ ,}"]+/\1[REDACTED]/Ig' \
|
||||
-e 's/(OPENAI_API_KEY[=: ]+)[^ ,}"]+/\1[REDACTED]/Ig' \
|
||||
-e 's/sk-[A-Za-z0-9_-]{12,}/sk-[REDACTED]/g' \
|
||||
-e 's/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/[EMAIL-REDACTED]/g' \
|
||||
| tail -200
|
||||
```
|
||||
|
||||
Useful excerpts usually include `openai/gpt-5.5` or `openai/gpt-5.4`,
|
||||
`Runtime: OpenAI Codex`, `agentRuntime.id` or `harnessRuntime`,
|
||||
`candidateProvider: "openai"`, and a `401`, `Incorrect API key`, or
|
||||
`No API key` result. A corrected run should show the `openai-codex` OAuth
|
||||
path instead of a plain OpenAI API-key failure.
|
||||
|
||||
**Legacy `openai-codex/*` config remains:** run `openclaw doctor --fix`.
|
||||
Doctor rewrites legacy model refs to `openai/*`, removes stale session and
|
||||
whole-agent runtime pins, and preserves existing auth-profile overrides.
|
||||
|
||||
@@ -150,4 +150,22 @@ describe("OpenAI Codex routing policy", () => {
|
||||
}),
|
||||
).toEqual(["openai-codex"]);
|
||||
});
|
||||
|
||||
it("routes openai provider to openai-codex when harness runtime is codex", () => {
|
||||
expect(
|
||||
resolveSelectedOpenAIPiRuntimeProvider({
|
||||
provider: "openai",
|
||||
harnessRuntime: "codex",
|
||||
}),
|
||||
).toBe("openai-codex");
|
||||
});
|
||||
|
||||
it("does not route non-OpenAI providers when runtime is codex", () => {
|
||||
expect(
|
||||
resolveSelectedOpenAIPiRuntimeProvider({
|
||||
provider: "anthropic",
|
||||
harnessRuntime: "codex",
|
||||
}),
|
||||
).toBe("anthropic");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -181,8 +181,13 @@ export function resolveSelectedOpenAIPiRuntimeProvider(params: {
|
||||
return OPENAI_CODEX_PROVIDER_ID;
|
||||
}
|
||||
const runtime = normalizeEmbeddedAgentRuntime(params.agentHarnessId ?? params.harnessRuntime);
|
||||
return isOpenAIProvider(params.provider) &&
|
||||
runtime === "pi" &&
|
||||
if (!isOpenAIProvider(params.provider)) {
|
||||
return params.provider;
|
||||
}
|
||||
if (runtime === "codex") {
|
||||
return OPENAI_CODEX_PROVIDER_ID;
|
||||
}
|
||||
return runtime === "pi" &&
|
||||
!params.authProfileId?.trim() &&
|
||||
configuredOpenAIAuthOrderStartsWithCodexProfile(params.config)
|
||||
? OPENAI_CODEX_PROVIDER_ID
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
mockedResolveAuthProfileOrder,
|
||||
mockedResolveContextWindowInfo,
|
||||
mockedResolveFailoverStatus,
|
||||
mockedResolveModelAsync,
|
||||
mockedRunContextEngineMaintenance,
|
||||
mockedRunEmbeddedAttempt,
|
||||
mockedSessionLikelyHasOversizedToolResults,
|
||||
@@ -496,7 +497,7 @@ describe("runEmbeddedPiAgent overflow compaction trigger routing", () => {
|
||||
expect(mockedBuildAgentRuntimePlan).toHaveBeenCalledTimes(1);
|
||||
expect(pluginRunAttempt).toHaveBeenCalledTimes(1);
|
||||
const pluginParams = expectMockCallFields(pluginRunAttempt, {
|
||||
provider: "openai",
|
||||
provider: "openai-codex",
|
||||
authProfileId: "openai-codex:work",
|
||||
authProfileIdSource: "user",
|
||||
});
|
||||
@@ -522,6 +523,272 @@ describe("runEmbeddedPiAgent overflow compaction trigger routing", () => {
|
||||
expect(successParams.profileId).toBe("openai-codex:work");
|
||||
});
|
||||
|
||||
it("bootstraps OAuth credentials for forced openai/* Codex response runs", async () => {
|
||||
const { clearAgentHarnesses, registerAgentHarness } = await import("../harness/registry.js");
|
||||
const pluginRunAttempt = vi.fn<AgentHarness["runAttempt"]>(async () =>
|
||||
makeAttemptResult({ assistantTexts: ["ok"] }),
|
||||
);
|
||||
const codexAuthStorage = {
|
||||
setRuntimeApiKey: vi.fn(),
|
||||
getApiKey: vi.fn(async () => "stored-test-key"),
|
||||
};
|
||||
const runtimePlan = makeForwardedRuntimePlan({
|
||||
resolvedRef: {
|
||||
provider: "openai-codex",
|
||||
modelId: "gpt-5.5",
|
||||
harnessId: "codex",
|
||||
},
|
||||
auth: {
|
||||
providerForAuth: "openai-codex",
|
||||
authProfileProviderForAuth: "openai-codex",
|
||||
harnessAuthProvider: "openai-codex",
|
||||
forwardedAuthProfileId: "openai-codex:work",
|
||||
},
|
||||
});
|
||||
const codexAuthStore = {
|
||||
version: 1 as const,
|
||||
profiles: {
|
||||
"openai-codex:work": {
|
||||
type: "oauth" as const,
|
||||
provider: "openai-codex",
|
||||
access: "access-token",
|
||||
refresh: "refresh-token",
|
||||
expires: Date.now() + 60_000,
|
||||
},
|
||||
},
|
||||
};
|
||||
clearAgentHarnesses();
|
||||
registerAgentHarness({
|
||||
id: "codex",
|
||||
label: "Codex",
|
||||
supports: () => ({ supported: false }),
|
||||
runAttempt: pluginRunAttempt,
|
||||
});
|
||||
mockedEnsureAuthProfileStoreWithoutExternalProfiles.mockReturnValueOnce(codexAuthStore);
|
||||
mockedResolveModelAsync
|
||||
.mockResolvedValueOnce({
|
||||
model: {
|
||||
id: "gpt-5.5",
|
||||
provider: "openai",
|
||||
contextWindow: 200000,
|
||||
api: "openai-responses",
|
||||
},
|
||||
error: null,
|
||||
authStorage: { setRuntimeApiKey: vi.fn() },
|
||||
modelRegistry: {},
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
model: {
|
||||
id: "gpt-5.5",
|
||||
provider: "openai-codex",
|
||||
contextWindow: 200000,
|
||||
api: "openai-codex-responses",
|
||||
},
|
||||
error: null,
|
||||
authStorage: codexAuthStorage,
|
||||
modelRegistry: {},
|
||||
});
|
||||
mockedBuildAgentRuntimePlan.mockReturnValueOnce(runtimePlan);
|
||||
|
||||
try {
|
||||
await runEmbeddedPiAgent({
|
||||
...overflowBaseRunParams,
|
||||
provider: "openai",
|
||||
model: "gpt-5.5",
|
||||
config: {
|
||||
agents: {
|
||||
defaults: {
|
||||
agentRuntime: { id: "codex" },
|
||||
},
|
||||
},
|
||||
},
|
||||
authProfileId: "openai-codex:work",
|
||||
authProfileIdSource: "user",
|
||||
runId: "forced-openai-codex-responses-bootstrap-oauth",
|
||||
});
|
||||
} finally {
|
||||
clearAgentHarnesses();
|
||||
}
|
||||
|
||||
expect(mockedGetApiKeyForModel).toHaveBeenCalledTimes(1);
|
||||
expectMockCallFields(mockedGetApiKeyForModel, {
|
||||
profileId: "openai-codex:work",
|
||||
});
|
||||
expect(codexAuthStorage.setRuntimeApiKey).toHaveBeenCalledWith("openai-codex", "test-key");
|
||||
expect(pluginRunAttempt).toHaveBeenCalledTimes(1);
|
||||
expectMockCallFields(pluginRunAttempt, {
|
||||
provider: "openai-codex",
|
||||
authProfileId: "openai-codex:work",
|
||||
authProfileIdSource: "user",
|
||||
resolvedApiKey: "test-key",
|
||||
});
|
||||
});
|
||||
|
||||
it("refreshes bootstrapped Codex OAuth credentials when rotating profiles", async () => {
|
||||
const { clearAgentHarnesses, registerAgentHarness } = await import("../harness/registry.js");
|
||||
const subscriptionLimit = new Error(
|
||||
"You've reached your Codex subscription usage limit. Next reset in 20 hours.",
|
||||
);
|
||||
const normalizedLimit = Object.assign(new Error(subscriptionLimit.message), {
|
||||
name: "FailoverError",
|
||||
reason: "rate_limit",
|
||||
status: 429,
|
||||
});
|
||||
let attemptCount = 0;
|
||||
const pluginRunAttempt = vi.fn<AgentHarness["runAttempt"]>(async () => {
|
||||
attemptCount += 1;
|
||||
return attemptCount === 1
|
||||
? makeAttemptResult({ promptError: subscriptionLimit })
|
||||
: makeAttemptResult({ assistantTexts: ["backup ok"], promptError: null });
|
||||
});
|
||||
const codexAuthStorage = {
|
||||
setRuntimeApiKey: vi.fn(),
|
||||
getApiKey: vi.fn(async () => "stored-test-key"),
|
||||
};
|
||||
const firstRuntimePlan = makeForwardedRuntimePlan({
|
||||
resolvedRef: {
|
||||
provider: "openai-codex",
|
||||
modelId: "gpt-5.5",
|
||||
harnessId: "codex",
|
||||
},
|
||||
auth: {
|
||||
providerForAuth: "openai-codex",
|
||||
authProfileProviderForAuth: "openai-codex",
|
||||
harnessAuthProvider: "openai-codex",
|
||||
forwardedAuthProfileId: "openai-codex:sub",
|
||||
forwardedAuthProfileCandidateIds: ["openai-codex:sub", "openai-codex:backup"],
|
||||
},
|
||||
});
|
||||
const secondRuntimePlan = makeForwardedRuntimePlan({
|
||||
resolvedRef: {
|
||||
provider: "openai-codex",
|
||||
modelId: "gpt-5.5",
|
||||
harnessId: "codex",
|
||||
},
|
||||
auth: {
|
||||
providerForAuth: "openai-codex",
|
||||
authProfileProviderForAuth: "openai-codex",
|
||||
harnessAuthProvider: "openai-codex",
|
||||
forwardedAuthProfileId: "openai-codex:backup",
|
||||
forwardedAuthProfileCandidateIds: ["openai-codex:sub", "openai-codex:backup"],
|
||||
},
|
||||
});
|
||||
const codexAuthStore = {
|
||||
version: 1 as const,
|
||||
profiles: {
|
||||
"openai-codex:sub": {
|
||||
type: "oauth" as const,
|
||||
provider: "openai-codex",
|
||||
access: "sub-access-token",
|
||||
refresh: "sub-refresh-token",
|
||||
expires: Date.now() + 60_000,
|
||||
},
|
||||
"openai-codex:backup": {
|
||||
type: "oauth" as const,
|
||||
provider: "openai-codex",
|
||||
access: "backup-access-token",
|
||||
refresh: "backup-refresh-token",
|
||||
expires: Date.now() + 60_000,
|
||||
},
|
||||
},
|
||||
};
|
||||
clearAgentHarnesses();
|
||||
registerAgentHarness({
|
||||
id: "codex",
|
||||
label: "Codex",
|
||||
supports: () => ({ supported: false }),
|
||||
runAttempt: pluginRunAttempt,
|
||||
});
|
||||
mockedEnsureAuthProfileStoreWithoutExternalProfiles.mockReturnValueOnce(codexAuthStore);
|
||||
mockedResolveAuthProfileOrder.mockReturnValueOnce(["openai-codex:sub", "openai-codex:backup"]);
|
||||
mockedResolveModelAsync
|
||||
.mockResolvedValueOnce({
|
||||
model: {
|
||||
id: "gpt-5.5",
|
||||
provider: "openai",
|
||||
contextWindow: 200000,
|
||||
api: "openai-responses",
|
||||
},
|
||||
error: null,
|
||||
authStorage: { setRuntimeApiKey: vi.fn() },
|
||||
modelRegistry: {},
|
||||
})
|
||||
.mockResolvedValueOnce({
|
||||
model: {
|
||||
id: "gpt-5.5",
|
||||
provider: "openai-codex",
|
||||
contextWindow: 200000,
|
||||
api: "openai-codex-responses",
|
||||
},
|
||||
error: null,
|
||||
authStorage: codexAuthStorage,
|
||||
modelRegistry: {},
|
||||
});
|
||||
mockedBuildAgentRuntimePlan
|
||||
.mockReturnValueOnce(firstRuntimePlan)
|
||||
.mockReturnValueOnce(secondRuntimePlan);
|
||||
mockedGetApiKeyForModel.mockImplementation(
|
||||
async ({ profileId }: { profileId?: string } = {}) => ({
|
||||
apiKey: profileId === "openai-codex:backup" ? "backup-token" : "sub-token",
|
||||
profileId: profileId ?? "openai-codex:sub",
|
||||
source: "test",
|
||||
mode: "api-key",
|
||||
}),
|
||||
);
|
||||
mockedCoerceToFailoverError.mockReturnValueOnce(normalizedLimit);
|
||||
mockedDescribeFailoverError.mockImplementation((err: unknown) => ({
|
||||
message: err instanceof Error ? err.message : String(err),
|
||||
reason: err === normalizedLimit ? "rate_limit" : undefined,
|
||||
status: err === normalizedLimit ? 429 : undefined,
|
||||
code: undefined,
|
||||
}));
|
||||
|
||||
try {
|
||||
await runEmbeddedPiAgent({
|
||||
...overflowBaseRunParams,
|
||||
provider: "openai",
|
||||
model: "gpt-5.5",
|
||||
config: {
|
||||
agents: {
|
||||
defaults: {
|
||||
agentRuntime: { id: "codex" },
|
||||
},
|
||||
},
|
||||
},
|
||||
runId: "forced-openai-codex-responses-rotates-oauth",
|
||||
});
|
||||
} finally {
|
||||
clearAgentHarnesses();
|
||||
}
|
||||
|
||||
expect(mockedGetApiKeyForModel).toHaveBeenCalledTimes(2);
|
||||
expect(codexAuthStorage.setRuntimeApiKey).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
"openai-codex",
|
||||
"sub-token",
|
||||
);
|
||||
expect(codexAuthStorage.setRuntimeApiKey).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
"openai-codex",
|
||||
"backup-token",
|
||||
);
|
||||
expect(pluginRunAttempt).toHaveBeenCalledTimes(2);
|
||||
expectMockCallFields(pluginRunAttempt, {
|
||||
provider: "openai-codex",
|
||||
authProfileId: "openai-codex:sub",
|
||||
resolvedApiKey: "sub-token",
|
||||
});
|
||||
expectMockCallFields(
|
||||
pluginRunAttempt,
|
||||
{
|
||||
provider: "openai-codex",
|
||||
authProfileId: "openai-codex:backup",
|
||||
resolvedApiKey: "backup-token",
|
||||
},
|
||||
1,
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps auto-selected OpenAI Codex auth profiles for forced codex harness runs", async () => {
|
||||
const { clearAgentHarnesses, registerAgentHarness } = await import("../harness/registry.js");
|
||||
const pluginRunAttempt = vi.fn<AgentHarness["runAttempt"]>(async () =>
|
||||
@@ -573,7 +840,7 @@ describe("runEmbeddedPiAgent overflow compaction trigger routing", () => {
|
||||
expect(mockedBuildAgentRuntimePlan).toHaveBeenCalledTimes(1);
|
||||
expect(pluginRunAttempt).toHaveBeenCalledTimes(1);
|
||||
const pluginParams = expectMockCallFields(pluginRunAttempt, {
|
||||
provider: "openai",
|
||||
provider: "openai-codex",
|
||||
authProfileId: "openai-codex:default",
|
||||
authProfileIdSource: "auto",
|
||||
});
|
||||
@@ -646,7 +913,7 @@ describe("runEmbeddedPiAgent overflow compaction trigger routing", () => {
|
||||
expect(mockedBuildAgentRuntimePlan).toHaveBeenCalledTimes(1);
|
||||
expect(pluginRunAttempt).toHaveBeenCalledTimes(1);
|
||||
const pluginParams = expectMockCallFields(pluginRunAttempt, {
|
||||
provider: "openai",
|
||||
provider: "openai-codex",
|
||||
authProfileId: "openai-codex:default",
|
||||
authProfileIdSource: "auto",
|
||||
});
|
||||
@@ -731,7 +998,7 @@ describe("runEmbeddedPiAgent overflow compaction trigger routing", () => {
|
||||
expect(mockedBuildAgentRuntimePlan).toHaveBeenCalledTimes(1);
|
||||
expect(pluginRunAttempt).toHaveBeenCalledTimes(1);
|
||||
const pluginParams = expectMockCallFields(pluginRunAttempt, {
|
||||
provider: "openai",
|
||||
provider: "openai-codex",
|
||||
authProfileId: "openai:personal",
|
||||
authProfileIdSource: "auto",
|
||||
});
|
||||
@@ -863,14 +1130,14 @@ describe("runEmbeddedPiAgent overflow compaction trigger routing", () => {
|
||||
expect(mockedGetApiKeyForModel).not.toHaveBeenCalled();
|
||||
expect(pluginRunAttempt).toHaveBeenCalledTimes(2);
|
||||
const firstAttempt = expectMockCallFields(pluginRunAttempt, {
|
||||
provider: "openai",
|
||||
provider: "openai-codex",
|
||||
authProfileId: "openai-codex:sub",
|
||||
authProfileIdSource: "auto",
|
||||
});
|
||||
const secondAttempt = expectMockCallFields(
|
||||
pluginRunAttempt,
|
||||
{
|
||||
provider: "openai",
|
||||
provider: "openai-codex",
|
||||
authProfileId: "openai:backup",
|
||||
authProfileIdSource: "auto",
|
||||
},
|
||||
|
||||
@@ -62,6 +62,7 @@ import {
|
||||
} from "../model-auth.js";
|
||||
import { ensureOpenClawModelsJson } from "../models-config.js";
|
||||
import {
|
||||
OPENAI_CODEX_PROVIDER_ID,
|
||||
listOpenAIAuthProfileProvidersForAgentRuntime,
|
||||
resolveContextConfigProviderForRuntime,
|
||||
resolveSelectedOpenAIPiRuntimeProvider,
|
||||
@@ -685,16 +686,22 @@ export async function runEmbeddedPiAgent(
|
||||
startupStages.mark("model-resolution");
|
||||
notifyExecutionPhase("model_resolution", { provider, model: modelId });
|
||||
|
||||
const authStore = pluginHarnessOwnsTransport
|
||||
? createEmptyAuthProfileStore()
|
||||
: ensureAuthProfileStoreWithoutExternalProfiles(agentDir, {
|
||||
allowKeychainPrompt: false,
|
||||
});
|
||||
const attemptAuthProfileStore = pluginHarnessOwnsTransport
|
||||
? ensureAuthProfileStoreWithoutExternalProfiles(agentDir, {
|
||||
allowKeychainPrompt: false,
|
||||
})
|
||||
: authStore;
|
||||
const pluginHarnessNeedsOpenClawAuthBootstrap =
|
||||
pluginHarnessOwnsTransport &&
|
||||
provider === OPENAI_CODEX_PROVIDER_ID &&
|
||||
effectiveModel.api === "openai-codex-responses";
|
||||
const authStore =
|
||||
pluginHarnessOwnsTransport && !pluginHarnessNeedsOpenClawAuthBootstrap
|
||||
? createEmptyAuthProfileStore()
|
||||
: ensureAuthProfileStoreWithoutExternalProfiles(agentDir, {
|
||||
allowKeychainPrompt: false,
|
||||
});
|
||||
const attemptAuthProfileStore =
|
||||
pluginHarnessOwnsTransport && !pluginHarnessNeedsOpenClawAuthBootstrap
|
||||
? ensureAuthProfileStoreWithoutExternalProfiles(agentDir, {
|
||||
allowKeychainPrompt: false,
|
||||
})
|
||||
: authStore;
|
||||
const requestedProfileId = params.authProfileId?.trim();
|
||||
const requestedProfileIsUserLocked = params.authProfileIdSource === "user";
|
||||
const isForwardablePluginHarnessAuthProfile = (
|
||||
@@ -943,11 +950,15 @@ export async function runEmbeddedPiAgent(
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const advanceAttemptAuthProfile =
|
||||
pluginHarnessOwnsTransport && !pluginHarnessNeedsOpenClawAuthBootstrap
|
||||
? advancePluginHarnessAuthProfile
|
||||
: advanceAuthProfile;
|
||||
|
||||
// Plugin harnesses own their model transport/auth. Running PI's generic
|
||||
// auth bootstrap here can turn synthetic provider markers into real
|
||||
// vendor-token refresh attempts before the plugin gets control.
|
||||
if (!pluginHarnessOwnsTransport) {
|
||||
if (!pluginHarnessOwnsTransport || pluginHarnessNeedsOpenClawAuthBootstrap) {
|
||||
await initializeAuthProfile();
|
||||
} else if (lockedProfileId) {
|
||||
lastProfileId = lockedProfileId;
|
||||
@@ -2277,9 +2288,7 @@ export async function runEmbeddedPiAgent(
|
||||
});
|
||||
if (
|
||||
promptFailoverDecision.action === "rotate_profile" &&
|
||||
(await (pluginHarnessOwnsTransport
|
||||
? advancePluginHarnessAuthProfile()
|
||||
: advanceAuthProfile()))
|
||||
(await advanceAttemptAuthProfile())
|
||||
) {
|
||||
if (failedPromptProfileId && promptProfileFailureReason) {
|
||||
void maybeMarkAuthProfileFailure({
|
||||
@@ -2509,9 +2518,7 @@ export async function runEmbeddedPiAgent(
|
||||
maybeMarkAuthProfileFailure,
|
||||
maybeEscalateRateLimitProfileFallback,
|
||||
maybeBackoffBeforeOverloadFailover,
|
||||
advanceAuthProfile: pluginHarnessOwnsTransport
|
||||
? advancePluginHarnessAuthProfile
|
||||
: advanceAuthProfile,
|
||||
advanceAuthProfile: advanceAttemptAuthProfile,
|
||||
});
|
||||
overloadProfileRotations = assistantFailoverOutcome.overloadProfileRotations;
|
||||
if (assistantFailoverOutcome.action === "retry") {
|
||||
|
||||
Reference in New Issue
Block a user