Skip to content

Commit 4ad0d0e

Browse files
committed
fix: align the credential functions to be the same
1 parent b55a776 commit 4ad0d0e

File tree

1 file changed

+52
-2
lines changed

1 file changed

+52
-2
lines changed

core/framework/tools/queen_lifecycle_tools.py

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1312,20 +1312,40 @@ async def list_credentials(credential_id: str = "") -> str:
13121312
Returns credential IDs, aliases, status, and identity metadata.
13131313
Never returns secret values. Optionally filter by credential_id.
13141314
"""
1315+
# Load shell config vars into os.environ — same first step as check-agent.
1316+
# Ensures keys set in ~/.zshrc/~/.bashrc are visible to is_available() checks.
1317+
try:
1318+
from framework.credentials.validation import ensure_credential_key_env
1319+
1320+
ensure_credential_key_env()
1321+
except Exception:
1322+
pass
1323+
13151324
try:
13161325
# Primary: CredentialStoreAdapter sees both Aden OAuth and local accounts
13171326
from aden_tools.credentials import CredentialStoreAdapter
13181327

13191328
store = CredentialStoreAdapter.default()
13201329
all_accounts = store.get_all_account_info()
13211330

1322-
# Filter by credential_id / provider if requested
1331+
# Filter by credential_id / provider if requested.
1332+
# A spec name like "gmail_oauth" maps to provider "google" via
1333+
# credential_id field — resolve that alias before filtering.
13231334
if credential_id:
1335+
try:
1336+
from aden_tools.credentials import CREDENTIAL_SPECS
1337+
1338+
spec = CREDENTIAL_SPECS.get(credential_id)
1339+
resolved_provider = (
1340+
(spec.credential_id or credential_id) if spec else credential_id
1341+
)
1342+
except Exception:
1343+
resolved_provider = credential_id
13241344
all_accounts = [
13251345
a
13261346
for a in all_accounts
13271347
if a.get("credential_id", "").startswith(credential_id)
1328-
or a.get("provider", "") == credential_id
1348+
or a.get("provider", "") in (credential_id, resolved_provider)
13291349
]
13301350

13311351
return json.dumps(
@@ -1342,13 +1362,43 @@ async def list_credentials(credential_id: str = "") -> str:
13421362

13431363
# Fallback: local encrypted store only
13441364
try:
1365+
from framework.credentials.local.models import LocalAccountInfo
13451366
from framework.credentials.local.registry import LocalCredentialRegistry
1367+
from framework.credentials.storage import EncryptedFileStorage
13461368

13471369
registry = LocalCredentialRegistry.default()
13481370
accounts = registry.list_accounts(
13491371
credential_id=credential_id or None,
13501372
)
13511373

1374+
# Also include flat-file credentials saved by the GUI (no "/" separator).
1375+
# LocalCredentialRegistry.list_accounts() skips these — read them directly.
1376+
seen_cred_ids = {info.credential_id for info in accounts}
1377+
storage = EncryptedFileStorage()
1378+
for storage_id in storage.list_all():
1379+
if "/" in storage_id:
1380+
continue # already handled by LocalCredentialRegistry above
1381+
if credential_id and storage_id != credential_id:
1382+
continue
1383+
if storage_id in seen_cred_ids:
1384+
continue
1385+
try:
1386+
cred_obj = storage.load(storage_id)
1387+
except Exception:
1388+
continue
1389+
if cred_obj is None:
1390+
continue
1391+
accounts.append(
1392+
LocalAccountInfo(
1393+
credential_id=storage_id,
1394+
alias="default",
1395+
status="unknown",
1396+
identity=cred_obj.identity,
1397+
last_validated=cred_obj.last_refreshed,
1398+
created_at=cred_obj.created_at,
1399+
)
1400+
)
1401+
13521402
credentials = []
13531403
for info in accounts:
13541404
entry: dict[str, Any] = {

0 commit comments

Comments
 (0)