Updating zero code sets of credentials, readme and manifest#1
Updating zero code sets of credentials, readme and manifest#1
Conversation
📝 WalkthroughWalkthroughThe 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
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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: OAuth2TokenManagerwill fail Pydantic validation onCustomLLMinstantiation.
CustomLLMinherits from Pydantic'sBaseModel. When storing non-Pydantic types (like the plainOAuth2TokenManagerclass) as fields, Pydantic requires either the field type to beAny, or the class to setarbitrary_types_allowed=True. The analogousCircuITLLMintravel_planner_k8s/main_server.pyusestoken_manager: Anyto avoid this validation error. Without fixing this, instantiation at line 193–199 will raise a PydanticValidationErrorat 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 = NoneProposed 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
#Optionaland#Debug settingswithout a space after#, while the rest of the file uses#consistently.Proposed fix
-#Optional +# Optional-#Debug settings +# Debug settingsAlso applies to: 46-46
instrumentation-genai/opentelemetry-instrumentation-llamaindex/examples/zero-code/README.rst (1)
78-78: Stale reference:server.addressdescribed 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: MissingContent-Lengthheader guard.Line 229 does
int(self.headers["Content-Length"])which raisesTypeErrorif 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)
| # 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 |
There was a problem hiding this comment.
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.
| 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 |
There was a problem hiding this comment.
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).
| # 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"), | ||
| ) |
There was a problem hiding this comment.
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.
Adding openai api key to zero code credentials
Updating readme
Updating deployment.yml
Summary by CodeRabbit
New Features
Documentation
Chores