Skip to content

If access_token -> then app_key is not required#168

Merged
vizsatiz merged 10 commits into
developfrom
fix_rootflo_llm
Nov 22, 2025
Merged

If access_token -> then app_key is not required#168
vizsatiz merged 10 commits into
developfrom
fix_rootflo_llm

Conversation

@rootflo-hardik
Copy link
Copy Markdown
Contributor

@rootflo-hardik rootflo-hardik commented Nov 22, 2025

Summary by CodeRabbit

  • New Features

    • RootFlo can be initialized with just a base URL and an access token; JWT fields (app key/secret/issuer/audience) are optional when using token-based auth.
    • Request headers will omit the app key header when no app key is provided.
  • Bug Fixes

    • Validation and error messages clarified: missing base_url is explicitly reported; JWT-related fields are not required or validated when an access token is used.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Nov 22, 2025

Walkthrough

Relaxed validation for RootFlo access-token flows: JWT parameters (app_key, app_secret, issuer, audience) are now optional. When using an access_token, only base_url is required. Constructor, helper signatures, header construction, and factory validation were updated to handle optional JWT fields.

Changes

Cohort / File(s) Summary
Factory validation
flo_ai/flo_ai/helpers/llm_factory.py
Simplified access-token branch validation to require only base_url; error message updated to reference missing base_url for access-token flow and JWT checks skipped when access_token is provided.
RootFlo LLM constructor & helpers
flo_ai/flo_ai/llm/rootflo_llm.py
Made app_key, app_secret, issuer, and audience optional (Optional[str] = None) in the constructor; removed enforcement of app_key when access_token is present; updated _fetch_llm_config_async signature to accept optional app_key.
Header and init behavior
flo_ai/flo_ai/llm/rootflo_llm.py
Conditioned inclusion of X-Rootflo-Key and related custom headers on presence of app_key; adjusted _ensure_initialized to pass empty/custom headers correctly and avoid sending empty/None header values.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant LLMFactory
    participant RootFloLLM

    rect rgb(245,250,255)
    Note over LLMFactory: Creation request
    User->>LLMFactory: create(base_url, model_id, access_token?, app_key?, ...)
    alt access_token provided
        LLMFactory->>RootFloLLM: init(base_url, model_id, access_token, app_key=None...)
        RootFloLLM->>RootFloLLM: _ensure_initialized(custom_headers={}) 
        RootFloLLM->>RootFloLLM: include X-Rootflo-Key only if app_key present
        RootFloLLM-->>User: instance (access-token flow)
    else no access_token
        LLMFactory->>RootFloLLM: init(base_url, model_id, app_key, app_secret, issuer, audience)
        RootFloLLM->>RootFloLLM: _fetch_llm_config_async(base_url, model_id, api_token, app_key)
        RootFloLLM-->>User: instance (JWT flow)
    end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Check call sites of RootFloLLM and llm_factory for assumptions that app_key/JWT fields are always present.
  • Verify header construction and any proxy-auth logic when app_key is None.
  • Confirm _fetch_llm_config_async usage and that optional app_key does not break downstream calls.

Possibly related PRs

Suggested reviewers

  • vizsatiz

Poem

🐰 I hopped through code with careful care,
base_url first — the rest needn't bear.
Tokens now dance, JWTs sit light,
headers appear only when they're right.
Cheers — RootFlo's field feels calm tonight! 🌿

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: making app_key optional when access_token is provided, which aligns with the actual code modifications across both files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix_rootflo_llm

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between baedf01 and f3f5fa4.

📒 Files selected for processing (2)
  • flo_ai/flo_ai/helpers/llm_factory.py (1 hunks)
  • flo_ai/flo_ai/llm/rootflo_llm.py (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • flo_ai/flo_ai/helpers/llm_factory.py
🔇 Additional comments (5)
flo_ai/flo_ai/llm/rootflo_llm.py (5)

35-38: LGTM! JWT parameters correctly made optional.

The constructor parameters are now optional with proper type hints. The validation logic at lines 68-84 correctly enforces that these parameters are required only when access_token is not provided, which aligns with the PR objective.


68-84: LGTM! Validation logic correctly enforces conditional requirements.

The validation correctly enforces that JWT parameters are required only when access_token is not provided. The implementation collects all missing parameters and provides a clear error message, which is good for developer experience.


117-121: LGTM! Method signature correctly updated.

The signature now includes self as the first parameter (which appears to be a bug fix, as this is called as an instance method on line 210) and correctly makes app_key optional. The docstring at line 130 has also been updated to reflect the optional nature of app_key.


143-145: LGTM! Conditional header logic correctly implemented.

The X-Rootflo-Key header is now only added when app_key is provided, which correctly supports the access token flow without requiring JWT parameters.


234-234: LGTM! Conditional header construction correctly implemented.

The custom_headers dictionary is now constructed conditionally using a clean ternary operator. When app_key is not provided, an empty dictionary is passed, which correctly supports the access token flow.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
flo_ai/flo_ai/helpers/llm_factory.py (1)

205-228: Access-token flow correctly relaxes requirements to just base_url

The new access-token branch now only enforces base_url and no longer requires app_key/JWT fields, which matches the PR objective and keeps the JWT path strict via the if not access_token branch. The error message also clearly documents all sources for base_url (model_config, kwargs, env). As a minor polish (optional), you might mirror the “model_config” wording in the JWT-branch error text for consistency, but functionally this looks solid.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 19b3395 and d737cc2.

📒 Files selected for processing (2)
  • flo_ai/flo_ai/helpers/llm_factory.py (1 hunks)
  • flo_ai/flo_ai/llm/rootflo_llm.py (5 hunks)
🔇 Additional comments (3)
flo_ai/flo_ai/llm/rootflo_llm.py (3)

31-85: Constructor changes safely support access-token–only initialization

Making app_key, app_secret, issuer, and audience Optional[str] = None while keeping the if not access_token validation preserves strict requirements for the JWT path but allows constructing RootFloLLM with only base_url, model_id, and an access_token. This is backward compatible with existing call sites and aligns with the “access_token → app_key not required” goal.


116-146: Optional app_key for config fetch avoids bogus header values

The updated _fetch_llm_config_async signature and header construction only add X-Rootflo-Key when app_key is truthy. This prevents sending an invalid X-Rootflo-Key: None header when using access-token–only auth, while still supporting scenarios where both access_token and app_key are supplied.


233-235: Proxy custom_headers behavior matches access-token semantics

Building custom_headers as {'X-Rootflo-Key': self._app_key} only when _app_key is set keeps downstream SDK wrappers consistent with the config-fetch behavior: access-token–only flows send no X-Rootflo-Key, while flows with an app_key continue to propagate it. This is a clean and minimal change.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
flo_ai/flo_ai/llm/rootflo_llm.py (2)

68-84: Consider logging when JWT credentials are ignored.

When both access_token and JWT credentials are provided, the JWT credentials are silently ignored. While the docstring mentions this behavior (line 53), adding a debug log or warning could improve developer experience by making this precedence explicit at runtime.

Example:

 if not access_token:
     missing = []
     if not app_key:
         missing.append('app_key')
     if not app_secret:
         missing.append('app_secret')
     if not issuer:
         missing.append('issuer')
     if not audience:
         missing.append('audience')

     if missing:
         raise ValueError(
             f'Missing required parameters for JWT generation: {", ".join(missing)}. '
             f'Either provide these parameters or pass an access_token directly.'
         )
+else:
+    # Log if JWT credentials are provided but will be ignored
+    if any([app_key, app_secret, issuer, audience]):
+        import logging
+        logging.debug("JWT credentials provided but will be ignored because access_token is present")

233-238: Minor: Redundant parentheses in ternary expression.

The outer parentheses in the ternary expression are unnecessary but don't affect functionality.

-custom_headers = (
-    {'X-Rootflo-Key': self._app_key}
-    if (self._app_key and self._access_token is None)
-    else {}
-)
+custom_headers = (
+    {'X-Rootflo-Key': self._app_key}
+    if self._app_key and self._access_token is None
+    else {}
+)

Note: The logic itself is correct and consistent with the header construction in _fetch_llm_config_async.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d737cc2 and baedf01.

📒 Files selected for processing (2)
  • flo_ai/flo_ai/helpers/llm_factory.py (1 hunks)
  • flo_ai/flo_ai/llm/rootflo_llm.py (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • flo_ai/flo_ai/helpers/llm_factory.py
🔇 Additional comments (3)
flo_ai/flo_ai/llm/rootflo_llm.py (3)

31-42: LGTM: Constructor signature correctly supports dual authentication paths.

The optional JWT parameters (app_key, app_secret, issuer, audience) align with the PR objective and enable both JWT-based and access_token-based authentication flows.


192-207: LGTM: JWT generation is safely guarded by validation.

The JWT generation code only executes when access_token is not provided, and the constructor validation (lines 68-84) ensures all required JWT credentials are present in this scenario.


116-146: LGTM: Header construction correctly distinguishes authentication modes.

The conditional logic for X-Rootflo-Key header (lines 143-145) appropriately adds the header only in JWT authentication mode (when app_key is provided and access_token is not used).

@vizsatiz vizsatiz merged commit ef928c2 into develop Nov 22, 2025
6 checks passed
@vizsatiz vizsatiz deleted the fix_rootflo_llm branch November 22, 2025 16:34
thomastomy5 pushed a commit that referenced this pull request Apr 27, 2026
* rootflo_llm -> lazy fetching llm config

- the fetch_llm_config call was synchronous, and if the server calling flo-ai and base_url are same, that was causing a deadlock.

* llm_factory -> added openai_vllm

* added OpenAIVLLM to rootflo_llm

* resolved comments

* resolved comments v2

* resolved comments v3

* if access_token -> then app_key not required

* if access_token -> passing other jwt params as None

* Revert "if access_token -> passing other jwt params as None"

This reverts commit baedf01.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants