fix(agent): reload credentials dynamically

This commit is contained in:
Jiang Bohan 2026-02-06 15:48:29 +08:00
parent 3b09d8d44d
commit 24df8b02e7
3 changed files with 106 additions and 11 deletions

View file

@ -95,6 +95,7 @@ export class Agent {
private profileCandidates: string[];
private profileIndex: number;
private readonly pinnedProfile: boolean;
private readonly explicitApiKey: boolean;
/** Current session ID */
readonly sessionId: string;
@ -126,6 +127,7 @@ export class Agent {
// === Auth profile resolution ===
this.pinnedProfile = !!(options.authProfileId || options.apiKey);
this.explicitApiKey = !!options.apiKey;
if (options.apiKey) {
// Explicit API key — no rotation
@ -159,11 +161,9 @@ export class Agent {
: 0;
}
this.agent = new PiAgentCore(
this.currentApiKey
? { getApiKey: (_provider: string) => this.currentApiKey! }
: {},
);
this.agent = new PiAgentCore({
getApiKey: (_provider: string) => this.currentApiKey ?? "",
});
// Load Agent Profile (if profileId is specified)
// Every Agent should have a Profile for memory, tools config, and other settings
@ -354,6 +354,10 @@ export class Agent {
async run(prompt: string): Promise<AgentRunResult> {
await this.ensureInitialized();
this.refreshAuthState();
if (!this.currentApiKey) {
throw new Error(`No API key configured for provider: ${this.resolvedProvider}`);
}
this.output.state.lastAssistantText = "";
const canRotate = !this.pinnedProfile && this.profileCandidates.length > 1;
@ -433,12 +437,67 @@ export class Agent {
this.currentApiKey = apiKey;
this.currentProfileId = candidateId;
this.profileIndex = nextIndex;
this.updateSessionApiKey();
return true;
}
return false;
}
private refreshAuthState(): void {
if (this.explicitApiKey) {
return;
}
const store = loadAuthProfileStore();
if (this.pinnedProfile) {
const profileId = this.currentProfileId ?? this.resolvedProvider;
this.currentApiKey = resolveApiKeyForProfile(profileId) ?? resolveApiKey(this.resolvedProvider);
this.currentProfileId = profileId;
this.profileCandidates = [];
this.profileIndex = 0;
this.updateSessionApiKey();
return;
}
const candidates = resolveAuthProfileOrder(this.resolvedProvider, store);
this.profileCandidates = candidates;
if (this.currentProfileId) {
const currentIndex = candidates.indexOf(this.currentProfileId);
if (currentIndex >= 0) {
const stats = store.usageStats?.[this.currentProfileId];
if (!stats || !isProfileInCooldown(stats)) {
const apiKey = resolveApiKeyForProfile(this.currentProfileId);
if (apiKey) {
this.currentApiKey = apiKey;
this.profileIndex = currentIndex;
this.updateSessionApiKey();
return;
}
}
}
}
const resolved = resolveApiKeyForProvider(this.resolvedProvider);
if (resolved) {
this.currentApiKey = resolved.apiKey;
this.currentProfileId = resolved.profileId;
this.profileIndex = Math.max(0, candidates.indexOf(resolved.profileId));
} else {
this.currentApiKey = undefined;
this.currentProfileId = undefined;
this.profileIndex = 0;
}
this.updateSessionApiKey();
}
private updateSessionApiKey(): void {
if (this.session.getCompactionMode() !== "summary") return;
this.session.setApiKey(this.currentApiKey);
}
private handleSessionEvent(event: AgentEvent) {
if (event.type === "message_end") {
const message = event.message as AgentMessage;
@ -680,6 +739,8 @@ export class Agent {
throw new Error(`No API key configured for provider: ${providerId}`);
}
this.updateSessionApiKey();
// Update the agent's model and API key
const baseUrl = resolveBaseUrl(actualProvider);
const modelWithBaseUrl = baseUrl ? { ...model, baseUrl } : model;