Conversation
…n unstripped A provider configured with key_cmd hands the resolver a CommandTokenSource (a lazy callable), not a str. The custom, named-custom, and registry branches of resolve_provider_client called .strip() on it and raised AttributeError, silently degrading title generation, smart approvals, and vision checks. Add a _strip_if_str helper — strings are stripped, callables pass through untouched (the wire clients accept a callable API key) — and use it at all three sites. Matches the existing idiom at the runtime record builder. Fixes NousResearch#113976. authored with AI assistance (Muse, Meta's Muse Spark) under the contributor's direction; reviewed and approved by the contributor before submission.
|
The callable still breaks in two auxiliary paths, so this does not yet fix #113976 end to end. First, _to_async_client() rebuilds AsyncOpenAI from sync_client.api_key. The OpenAI client stores a callable in _api_key_provider while api_key is an empty string. A direct probe at this head produced an async client with no callable provider and empty auth_headers, so async auxiliary calls are unauthenticated. Second, the main-runtime reuse branch still runs str(main_runtime.get("api_key") or "").strip() at agent/auxiliary_client.py:4796. A direct resolver probe converted a CommandTokenSource into its object representation, which would be sent as the bearer token. The new tests verify pass-through at the three changed strip sites, but they do not exercise the async client used by auxiliary calls or the main-runtime reuse path. Please preserve the callable token source through both paths and add regressions that inspect the effective async authorization behavior and the credential passed by main-runtime reuse. |
|
Closing as implemented/superseded on main. #114333 landed the callable |
What
key_cmdconfigured providers crashed auxiliary calls when aCommandTokenSourcecallable reached the resolution path:.strip()was called unconditionally on a non-string. New_strip_if_strhelper strips strings and passes callables through untouched, applied at all three crash sites (_resolve_custom_branch,_resolve_named_custom_branch,_resolve_registry_branch).Related Issue
Fixes #113976
Type
Changes
agent/auxiliary_client.py(+12/-3):_strip_if_strhelper + 3 call sitesHow to Test
scripts/run_tests.sh tests/agent/test_auxiliary_client.py— 2 new invariant tests pass; both fail on base with the issue's exactAttributeError: 'CommandTokenSource' object has no attribute 'strip'test_auxiliary_client.py+test_command_token_source.py= 243 passed, 2 failed (both verified pre-existing on base, untouched files); 4 additional aux-resolution suites 136/136 greenFollow-up (not in scope here):
str()coercion of the callable inhermes_cli/runtime_provider.py:640and related paths sends the callable's repr as a Bearer token and fails auth silently — behavioral change, worth a separate decision.Checklist
authored with AI assistance (Muse, Meta's Muse Spark) under the contributor's direction; reviewed and approved by the contributor before submission.