Skip to content

Updating zero code sets of credentials, readme and manifest#1

Open
shuningc wants to merge 1 commit intomainfrom
test-branch
Open

Updating zero code sets of credentials, readme and manifest#1
shuningc wants to merge 1 commit intomainfrom
test-branch

Conversation

@shuningc
Copy link
Owner

@shuningc shuningc commented Feb 6, 2026

Adding openai api key to zero code credentials
Updating readme
Updating deployment.yml

Summary by CodeRabbit

  • New Features

    • Added dual-authentication support: OAuth2 gateway mode and OpenAI API key fallback for flexible LLM configuration.
    • Introduced token management and automatic token refresh capabilities.
  • Documentation

    • Updated configuration guides with examples for both authentication modes.
    • Added deployment instructions for Kubernetes and Docker environments.
  • Chores

    • Updated dependencies for enhanced OpenTelemetry instrumentation and evaluation capabilities.

@coderabbitai
Copy link

coderabbitai bot commented Feb 6, 2026

📝 Walkthrough

Walkthrough

The changes introduce dual-authentication support (OAuth2 gateway and OpenAI API key) for the LlamaIndex zero-code example. Configuration, deployment manifests, and server logic were updated to support flexible LLM provider selection. Dependencies for OpenTelemetry instrumentation and evaluation tools were added.

Changes

Cohort / File(s) Summary
Configuration & Example Setup
.env.example, requirements.txt
Replaced Cisco Circuit configuration with OAuth2 gateway mode and OpenAI fallback mode. Added OTLP exporter, logging, metrics, and DeepEval-related variables. Introduced new dependencies including OpenTelemetry distro, OTLP exporter, and Splunk Otel instrumentation packages.
Documentation
README.rst
Updated setup instructions to reflect dual-auth configuration (OAuth2 gateway vs OpenAI), expanded environment variables section, added explicit OTLP endpoint guidance, and revised Docker/Kubernetes deployment examples with new credential handling.
Deployment Configuration
deployment.yaml
Replaced CIRCUIT_\* environment variables with LLM_\* equivalents, updated secret references from circuit-credentials to llm-credentials, and introduced OpenAI API key and model name variables with optional flag support.
Server Logic
server.py
Implemented OAuth2TokenManager for token caching and refresh, introduced CircaITLLM class for OAuth2-based chat, refactored initialize\_llm() to support dual-path LLM selection (OAuth2 gateway vs OpenAI API key), and added health endpoint.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant App as LLM App<br/>(server.py)
    participant OAuth2 as OAuth2<br/>Authorization<br/>Server
    participant CircuIT as CircuIT<br/>LLM Gateway
    participant OpenAI as OpenAI<br/>API
    
    Client->>App: POST /chat
    alt OAuth2 Gateway Mode (LLM_CLIENT_ID set)
        App->>OAuth2: Request token<br/>(client_credentials)
        OAuth2-->>App: Access token
        App->>App: Cache token<br/>(with refresh logic)
        App->>CircuIT: POST /chat<br/>(with token, optional app_key)
        CircuIT-->>App: LLM response
    else OpenAI API Mode (OPENAI_API_KEY set)
        App->>OpenAI: POST /chat/completions<br/>(with API key)
        OpenAI-->>App: LLM response
    end
    App-->>Client: Chat response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hops with glee through OAuth flows,
Two paths now where one path goes,
CircuIT gates or OpenAI's call,
Token refresh handles it all!
With OTEL tracing shining bright,

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: updating configuration files, environment variables, and documentation for the zero-code example to support dual authentication modes (OAuth2 and OpenAI).

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 test-branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link

@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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
instrumentation-genai/opentelemetry-instrumentation-llamaindex/examples/zero-code/server.py (1)

98-106: ⚠️ Potential issue | 🔴 Critical

token_manager: OAuth2TokenManager will fail Pydantic validation on CustomLLM instantiation.

CustomLLM inherits from Pydantic's BaseModel. When storing non-Pydantic types (like the plain OAuth2TokenManager class) as fields, Pydantic requires either the field type to be Any, or the class to set arbitrary_types_allowed=True. The analogous CircuITLLM in travel_planner_k8s/main_server.py uses token_manager: Any to avoid this validation error. Without fixing this, instantiation at line 193–199 will raise a Pydantic ValidationError at runtime.

Proposed fix (option A — match travel_planner pattern)
 class CircuITLLM(CustomLLM):
     """Custom LLM implementation for Cisco CircuIT gateway."""

     api_url: str
-    token_manager: OAuth2TokenManager
+    token_manager: Any
     app_key: str | None = None
Proposed fix (option B — allow arbitrary types, aligns with LlamaIndex patterns)
 class CircuITLLM(CustomLLM):
     """Custom LLM implementation for Cisco CircuIT gateway."""

+    model_config = {"arbitrary_types_allowed": True}
+
     api_url: str
     token_manager: OAuth2TokenManager
     app_key: str | None = None
🤖 Fix all issues with AI agents
In
`@instrumentation-genai/opentelemetry-instrumentation-llamaindex/examples/zero-code/README.rst`:
- Around line 186-190: The README currently says "Start the Splunk Distribution
of the OpenTelemetry Collector" but the docker command uses the community image
`otel/opentelemetry-collector`; update this mismatch by either changing the
heading text to "Start the OpenTelemetry Collector" to match the image
`otel/opentelemetry-collector`, or replace the docker image in the code block
with the Splunk distribution image `quay.io/signalfx/splunk-otel-collector` so
the command matches the "Splunk Distribution" description (edit the text and the
docker run line accordingly).
- Around line 102-119: The README has two LLM configuration examples in one
block where LLM_BASE_URL is defined twice, which is confusing; separate the
generic template and the Cisco CircuIT example into distinct sections (or
clearly mark the CircuIT lines as an alternative example) so values don’t appear
to overwrite each other—move the Cisco-specific lines (the second LLM_BASE_URL,
LLM_TOKEN_URL, LLM_CLIENT_ID, LLM_CLIENT_SECRET, LLM_APP_KEY, LLM_SCOPE) into a
new example block titled e.g. “Example: Cisco CircuIT Configuration” or prefix
them with a comment indicating they are an alternative, keeping the generic
template (OPENAI_API_KEY, LLM_CLIENT_ID, LLM_CLIENT_SECRET, LLM_TOKEN_URL,
LLM_BASE_URL, LLM_APP_KEY, LLM_SCOPE) separate.

In
`@instrumentation-genai/opentelemetry-instrumentation-llamaindex/examples/zero-code/server.py`:
- Around line 81-95: The module-level OAuth2 initialization uses USE_OAUTH2
based only on LLM_CLIENT_ID and constructs OAuth2TokenManager with possibly
empty token_url or client_secret, causing confusing runtime errors; update the
logic in the OAuth2 setup (token_manager, USE_OAUTH2, OAuth2TokenManager) to
either defer creation until initialize_llm() or validate required env vars
(LLM_TOKEN_URL, LLM_CLIENT_SECRET, LLM_CLIENT_ID, optionally LLM_SCOPE) up front
and raise a clear startup error if any are missing, so initialize_llm() only
receives a fully-formed token_manager or None.
🧹 Nitpick comments (4)
instrumentation-genai/opentelemetry-instrumentation-llamaindex/examples/zero-code/requirements.txt (1)

4-10: New dependencies lack version pins, inconsistent with existing entries.

Lines 1–3 use >= pins, but lines 4–10 have no version constraints. This creates reproducibility risk — a future breaking release of any of these packages could silently break the example.

At minimum, add >= lower-bound pins matching the versions you tested with, consistent with the style on lines 1–3.

instrumentation-genai/opentelemetry-instrumentation-llamaindex/examples/zero-code/.env.example (1)

36-36: Minor: inconsistent comment formatting.

Lines 36 and 46 use #Optional and #Debug settings without a space after #, while the rest of the file uses # consistently.

Proposed fix
-#Optional
+# Optional
-#Debug settings
+# Debug settings

Also applies to: 46-46

instrumentation-genai/opentelemetry-instrumentation-llamaindex/examples/zero-code/README.rst (1)

78-78: Stale reference: server.address described as "CircuIT API server address".

With dual-mode support, this could also be the OpenAI API server. Consider updating to a generic description like "LLM API server address".

instrumentation-genai/opentelemetry-instrumentation-llamaindex/examples/zero-code/server.py (1)

226-270: Missing Content-Length header guard.

Line 229 does int(self.headers["Content-Length"]) which raises TypeError if the header is missing, resulting in an unhandled 500. A simple guard would improve robustness:

Proposed fix
     def do_POST(self):
         """Handle POST requests for chat."""
         if self.path == "/chat":
-            content_length = int(self.headers["Content-Length"])
+            content_length = self.headers.get("Content-Length")
+            if content_length is None:
+                self.send_response(411)
+                self.end_headers()
+                return
+            content_length = int(content_length)
             post_data = self.rfile.read(content_length)

Comment on lines +102 to +119
# OpenAI API Key
OPENAI_API_KEY=sk-YOUR_API_KEY

# Or OAuth2 LLM Provider (for enterprise deployments)
LLM_CLIENT_ID=<your-oauth2-client-id>
LLM_CLIENT_SECRET=<your-oauth2-client-secret>
LLM_TOKEN_URL=https://<your-identity-provider>/oauth2/token
LLM_BASE_URL=https://<your-llm-gateway>/openai/deployments
LLM_APP_KEY=<your-app-key> # Optional
LLM_SCOPE=<scope> # Optional

# Example: Cisco CircuIT Configuration
LLM_BASE_URL=https://your-circuit-gateway.cisco.com/v1
LLM_TOKEN_URL=https://your-circuit-gateway.cisco.com/oauth2/token
LLM_CLIENT_ID=your_client_id_here
LLM_CLIENT_SECRET=your_secret_here
LLM_APP_KEY=llamaindex-zero-code-demo
LLM_SCOPE=api.read
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

LLM_BASE_URL is defined twice in the same code block — confusing for users.

Lines 109 and 114 both set LLM_BASE_URL. Because they appear in a single continuous block, it reads as if the second value overwrites the first. Split this into two separate blocks (one generic template, one CircuIT-specific example) or use comments to clearly delineate that the CircuIT section is an alternative example.

Proposed fix — separate the blocks
        LLM_APP_KEY=<your-app-key>  # Optional
        LLM_SCOPE=<scope>  # Optional

-       # Example: Cisco CircuIT Configuration
-       LLM_BASE_URL=https://your-circuit-gateway.cisco.com/v1
-       LLM_TOKEN_URL=https://your-circuit-gateway.cisco.com/oauth2/token
-       LLM_CLIENT_ID=your_client_id_here
-       LLM_CLIENT_SECRET=your_secret_here
-       LLM_APP_KEY=llamaindex-zero-code-demo
-       LLM_SCOPE=api.read
+
+   Example Cisco CircuIT configuration:
+
+   .. code-block:: console
+
+       LLM_BASE_URL=https://your-circuit-gateway.cisco.com/v1
+       LLM_TOKEN_URL=https://your-circuit-gateway.cisco.com/oauth2/token
+       LLM_CLIENT_ID=your_client_id_here
+       LLM_CLIENT_SECRET=your_secret_here
+       LLM_APP_KEY=llamaindex-zero-code-demo
+       LLM_SCOPE=api.read
🤖 Prompt for AI Agents
In
`@instrumentation-genai/opentelemetry-instrumentation-llamaindex/examples/zero-code/README.rst`
around lines 102 - 119, The README has two LLM configuration examples in one
block where LLM_BASE_URL is defined twice, which is confusing; separate the
generic template and the Cisco CircuIT example into distinct sections (or
clearly mark the CircuIT lines as an alternative example) so values don’t appear
to overwrite each other—move the Cisco-specific lines (the second LLM_BASE_URL,
LLM_TOKEN_URL, LLM_CLIENT_ID, LLM_CLIENT_SECRET, LLM_APP_KEY, LLM_SCOPE) into a
new example block titled e.g. “Example: Cisco CircuIT Configuration” or prefix
them with a comment indicating they are an alternative, keeping the generic
template (OPENAI_API_KEY, LLM_CLIENT_ID, LLM_CLIENT_SECRET, LLM_TOKEN_URL,
LLM_BASE_URL, LLM_APP_KEY, LLM_SCOPE) separate.

Comment on lines +186 to +190
1. Start the Splunk Distribution of the OpenTelemetry Collector (example using Docker):

.. code-block:: console

export CIRCUIT_BASE_URL="https://chat-ai.cisco.com/openai/deployments/gpt-4o-mini/chat/completions"
export CIRCUIT_TOKEN_URL="https://id.cisco.com/oauth2/default/v1/token"
export CIRCUIT_CLIENT_ID="your-client-id"
export CIRCUIT_CLIENT_SECRET="your-client-secret"
export CIRCUIT_APP_KEY="your-app-key"
export OTEL_SERVICE_NAME="llamaindex-zero-code-server"
export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT="true"
export OTEL_INSTRUMENTATION_GENAI_EMITTERS="span_metric_event"
docker run -p 4317:4317 -p 4318:4318 otel/opentelemetry-collector
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Collector image doesn't match "Splunk Distribution" description.

Line 186 says "Start the Splunk Distribution of the OpenTelemetry Collector" but line 190 uses the community image otel/opentelemetry-collector. Either update the text to say "OpenTelemetry Collector" or use the Splunk distribution image (quay.io/signalfx/splunk-otel-collector).

🤖 Prompt for AI Agents
In
`@instrumentation-genai/opentelemetry-instrumentation-llamaindex/examples/zero-code/README.rst`
around lines 186 - 190, The README currently says "Start the Splunk Distribution
of the OpenTelemetry Collector" but the docker command uses the community image
`otel/opentelemetry-collector`; update this mismatch by either changing the
heading text to "Start the OpenTelemetry Collector" to match the image
`otel/opentelemetry-collector`, or replace the docker image in the code block
with the Splunk distribution image `quay.io/signalfx/splunk-otel-collector` so
the command matches the "Splunk Distribution" description (edit the text and the
docker run line accordingly).

Comment on lines +81 to +95
# Optional app key for request tracking
LLM_APP_KEY = os.environ.get("LLM_APP_KEY")

# Check if we should use OAuth2 or standard OpenAI
USE_OAUTH2 = bool(os.environ.get("LLM_CLIENT_ID"))

# Initialize token manager if OAuth2 credentials are present
token_manager: OAuth2TokenManager | None = None
if USE_OAUTH2:
token_manager = OAuth2TokenManager(
token_url=os.environ.get("LLM_TOKEN_URL", ""),
client_id=os.environ.get("LLM_CLIENT_ID", ""),
client_secret=os.environ.get("LLM_CLIENT_SECRET", ""),
scope=os.environ.get("LLM_SCOPE"),
)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Module-level OAuth2 init doesn't validate that all required fields are present.

USE_OAUTH2 is derived solely from LLM_CLIENT_ID being set (line 85), but token_url and client_secret fall back to empty strings if their env vars are missing (lines 91–93). This will produce a confusing HTTP error at token-fetch time rather than a clear startup error.

Consider validating upfront or deferring the check to initialize_llm():

Proposed fix — validate in initialize_llm
     if USE_OAUTH2 and token_manager:
         if not llm_base_url:
             raise RuntimeError(
                 "LLM_BASE_URL is required when using OAuth2 gateway credentials."
             )
+        missing = [v for v in ("LLM_TOKEN_URL", "LLM_CLIENT_SECRET") if not os.getenv(v)]
+        if missing:
+            raise RuntimeError(
+                f"OAuth2 mode requires these env vars: {', '.join(missing)}"
+            )
🤖 Prompt for AI Agents
In
`@instrumentation-genai/opentelemetry-instrumentation-llamaindex/examples/zero-code/server.py`
around lines 81 - 95, The module-level OAuth2 initialization uses USE_OAUTH2
based only on LLM_CLIENT_ID and constructs OAuth2TokenManager with possibly
empty token_url or client_secret, causing confusing runtime errors; update the
logic in the OAuth2 setup (token_manager, USE_OAUTH2, OAuth2TokenManager) to
either defer creation until initialize_llm() or validate required env vars
(LLM_TOKEN_URL, LLM_CLIENT_SECRET, LLM_CLIENT_ID, optionally LLM_SCOPE) up front
and raise a clear startup error if any are missing, so initialize_llm() only
receives a fully-formed token_manager or None.

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.

1 participant