fix: restore auth fallback ordering
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
### Fixes
|
||||
- Onboarding: resolve CLI entrypoint when running via `npx` so gateway daemon install works without a build step.
|
||||
- CLI: auto-migrate legacy config entries on command start (same behavior as gateway startup).
|
||||
- Auth: prioritize OAuth profiles but fall back to API keys when refresh fails; stored profiles now load without explicit auth order.
|
||||
- Linux: auto-attempt lingering during onboarding (try without sudo, fallback to sudo) and prompt on install/restart to keep the gateway alive after logout/idle. Thanks @tobiasbischoff for PR #237.
|
||||
- TUI: migrate key handling to the updated pi-tui Key matcher API.
|
||||
- Logging: redact sensitive tokens in verbose tool summaries by default (configurable patterns).
|
||||
|
||||
@@ -30,12 +30,12 @@ describe("resolveAuthProfileOrder", () => {
|
||||
},
|
||||
};
|
||||
|
||||
it("returns empty order without explicit config", () => {
|
||||
it("uses stored profiles when no config exists", () => {
|
||||
const order = resolveAuthProfileOrder({
|
||||
store,
|
||||
provider: "anthropic",
|
||||
});
|
||||
expect(order).toEqual([]);
|
||||
expect(order).toEqual(["anthropic:default", "anthropic:work"]);
|
||||
});
|
||||
|
||||
it("prioritizes preferred profiles", () => {
|
||||
@@ -80,4 +80,29 @@ describe("resolveAuthProfileOrder", () => {
|
||||
});
|
||||
expect(order).toEqual(["anthropic:work", "anthropic:default"]);
|
||||
});
|
||||
|
||||
it("prioritizes oauth profiles when order missing", () => {
|
||||
const mixedStore: AuthProfileStore = {
|
||||
version: 1,
|
||||
profiles: {
|
||||
"anthropic:default": {
|
||||
type: "api_key",
|
||||
provider: "anthropic",
|
||||
key: "sk-default",
|
||||
},
|
||||
"anthropic:oauth": {
|
||||
type: "oauth",
|
||||
provider: "anthropic",
|
||||
access: "access-token",
|
||||
refresh: "refresh-token",
|
||||
expires: Date.now() + 60_000,
|
||||
},
|
||||
},
|
||||
};
|
||||
const order = resolveAuthProfileOrder({
|
||||
store: mixedStore,
|
||||
provider: "anthropic",
|
||||
});
|
||||
expect(order).toEqual(["anthropic:oauth", "anthropic:default"]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -258,10 +258,16 @@ export function resolveAuthProfileOrder(params: {
|
||||
.map(([profileId]) => profileId)
|
||||
: [];
|
||||
const lastGood = store.lastGood?.[provider];
|
||||
const order =
|
||||
const baseOrder =
|
||||
configuredOrder ??
|
||||
(explicitProfiles.length > 0 ? explicitProfiles : undefined);
|
||||
if (!order) return [];
|
||||
(explicitProfiles.length > 0
|
||||
? explicitProfiles
|
||||
: listProfilesForProvider(store, provider));
|
||||
if (baseOrder.length === 0) return [];
|
||||
const order =
|
||||
configuredOrder && configuredOrder.length > 0
|
||||
? baseOrder
|
||||
: orderProfilesByMode(baseOrder, store);
|
||||
|
||||
const filtered = order.filter((profileId) => {
|
||||
const cred = store.profiles[profileId];
|
||||
@@ -288,6 +294,20 @@ export function resolveAuthProfileOrder(params: {
|
||||
return deduped;
|
||||
}
|
||||
|
||||
function orderProfilesByMode(
|
||||
order: string[],
|
||||
store: AuthProfileStore,
|
||||
): string[] {
|
||||
const scored = order.map((profileId) => {
|
||||
const type = store.profiles[profileId]?.type;
|
||||
const score = type === "oauth" ? 0 : type === "api_key" ? 1 : 2;
|
||||
return { profileId, score };
|
||||
});
|
||||
return scored
|
||||
.sort((a, b) => a.score - b.score)
|
||||
.map((entry) => entry.profileId);
|
||||
}
|
||||
|
||||
export async function resolveApiKeyForProfile(params: {
|
||||
cfg?: ClawdbotConfig;
|
||||
store: AuthProfileStore;
|
||||
|
||||
@@ -374,8 +374,11 @@ export async function compactEmbeddedPiSession(params: {
|
||||
};
|
||||
}
|
||||
try {
|
||||
const apiKey = await getApiKeyForModel(model, authStorage);
|
||||
authStorage.setRuntimeApiKey(model.provider, apiKey);
|
||||
const apiKey = await getApiKeyForModel({
|
||||
model,
|
||||
cfg: params.config,
|
||||
});
|
||||
authStorage.setRuntimeApiKey(model.provider, apiKey.apiKey);
|
||||
} catch (err) {
|
||||
return {
|
||||
ok: false,
|
||||
|
||||
@@ -108,7 +108,9 @@ describe("sendMessageDiscord", () => {
|
||||
|
||||
it("adds missing permission hints on 50013", async () => {
|
||||
const { rest, postMock, getMock } = makeRest();
|
||||
const perms = new PermissionsBitField([PermissionsBitField.Flags.ViewChannel]);
|
||||
const perms = new PermissionsBitField([
|
||||
PermissionsBitField.Flags.ViewChannel,
|
||||
]);
|
||||
const apiError = Object.assign(new Error("Missing Permissions"), {
|
||||
code: 50013,
|
||||
status: 403,
|
||||
|
||||
Reference in New Issue
Block a user