agent config and format update#483
Conversation
📝 WalkthroughWalkthroughThis pull request transforms an example from a simple random-quote responder into a full conversational AI agent. The change introduces an Agent powered by OpenRouter with DuckDuckGo search capabilities, updates the Bindu configuration with skills and CORS settings, and refactors the handler to accept typed message dictionaries that are delegated to the agent for response generation. Changes
Sequence DiagramsequenceDiagram
participant Client
participant Handler
participant Agent
participant OpenRouter as OpenRouter Model
participant DuckDuckGo as DuckDuckGo Tools
Client->>Handler: messages: list[dict[str, str]]
Handler->>Agent: agent.run(input=messages)
Agent->>OpenRouter: Query with context
OpenRouter-->>Agent: Response (may include tool call)
alt Tool invocation needed
Agent->>DuckDuckGo: Search query
DuckDuckGo-->>Agent: Search results
Agent->>OpenRouter: Refined query with results
OpenRouter-->>Agent: Final response
end
Agent-->>Handler: Generated response
Handler-->>Client: Response message
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
🧹 Nitpick comments (1)
examples/beginner/motivational_agent.py (1)
56-61: Consider makingcors_originsconfigurable.Hardcoding
http://localhost:5173limits the example to a single front-end dev setup. Consider pulling from an env var (e.g.,CORS_ORIGINS) so users don't need to edit source to test different clients or deploy.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@examples/beginner/motivational_agent.py` around lines 56 - 61, The example hardcodes cors_origins inside the "deployment" dict; change it to read from an environment variable (e.g., CORS_ORIGINS) and fall back to the current default ["http://localhost:5173"]. Specifically, replace the static "cors_origins" value with logic that reads os.environ.get("CORS_ORIGINS"), splits on commas (and strips whitespace) when present, and converts it to a list; keep the existing list as the default if the env var is missing or empty. Update the "deployment" dict (the "cors_origins" key) accordingly and ensure any import of os is added if not already present so the code remains functional.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@examples/beginner/motivational_agent.py`:
- Line 80: The top-level call bindufy(config, handler) starts a blocking server
on import; move that call into a main guard by wrapping it inside if __name__ ==
"__main__": so importing the module won't start uvicorn—i.e., remove or comment
the bare bindufy(config, handler) and add a guarded call under if __name__ ==
"__main__": bindufy(config, handler), ensuring config and handler remain in
scope for the guarded invocation.
- Around line 66-76: The handler currently returns the raw RunResponse from
agent.run, which contradicts the bindufy() example that extracts and returns the
serialized content; update handler to call agent.run(input=messages), convert
the result to a dict and return only the "content" field (e.g., use
result.to_dict()["content"]) so the handler returns a JSON-serializable payload
consistent with bindufy()'s documented pattern; ensure you reference the handler
function and agent.run and handle missing keys or None safely before returning.
- Around line 41-44: The OpenRouter client is constructed with
api_key=os.getenv("OPENROUTER_API_KEY") which can be None if the env is
misconfigured; add a fail-fast check before creating the OpenRouter instance to
validate the OPENROUTER_API_KEY and raise a clear error if missing. Locate the
OpenRouter instantiation (model=OpenRouter(...)) in motivational_agent.py and,
prior to that line, read / validate the environment variable (e.g., get the
value into a local variable), and if it's empty/None, raise a RuntimeError or
exit with a descriptive message about the missing OPENROUTER_API_KEY so startup
fails fast and explains the misconfiguration.
---
Nitpick comments:
In `@examples/beginner/motivational_agent.py`:
- Around line 56-61: The example hardcodes cors_origins inside the "deployment"
dict; change it to read from an environment variable (e.g., CORS_ORIGINS) and
fall back to the current default ["http://localhost:5173"]. Specifically,
replace the static "cors_origins" value with logic that reads
os.environ.get("CORS_ORIGINS"), splits on commas (and strips whitespace) when
present, and converts it to a list; keep the existing list as the default if the
env var is missing or empty. Update the "deployment" dict (the "cors_origins"
key) accordingly and ensure any import of os is added if not already present so
the code remains functional.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ff212c3a-0cfa-4917-89e5-a944bd34f381
📒 Files selected for processing (1)
examples/beginner/motivational_agent.py
| model=OpenRouter( | ||
| id="openai/gpt-oss-120b", | ||
| api_key=os.getenv("OPENROUTER_API_KEY") | ||
| ), |
There was a problem hiding this comment.
Validate OPENROUTER_API_KEY presence.
If .env is missing or misconfigured, os.getenv("OPENROUTER_API_KEY") silently returns None and failures will only surface at first request with an opaque auth error. A fail-fast check at startup makes misconfiguration obvious.
🛠️ Suggested fix
+api_key = os.getenv("OPENROUTER_API_KEY")
+if not api_key:
+ raise RuntimeError("OPENROUTER_API_KEY is not set. Add it to your .env file.")
+
agent = Agent(
...
model=OpenRouter(
id="openai/gpt-oss-120b",
- api_key=os.getenv("OPENROUTER_API_KEY")
+ api_key=api_key,
),🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@examples/beginner/motivational_agent.py` around lines 41 - 44, The OpenRouter
client is constructed with api_key=os.getenv("OPENROUTER_API_KEY") which can be
None if the env is misconfigured; add a fail-fast check before creating the
OpenRouter instance to validate the OPENROUTER_API_KEY and raise a clear error
if missing. Locate the OpenRouter instantiation (model=OpenRouter(...)) in
motivational_agent.py and, prior to that line, read / validate the environment
variable (e.g., get the value into a local variable), and if it's empty/None,
raise a RuntimeError or exit with a descriptive message about the missing
OPENROUTER_API_KEY so startup fails fast and explains the misconfiguration.
| def handler(messages: list[dict[str, str]]): | ||
| """Process messages and return agent response. | ||
|
|
||
| Args: | ||
| messages: List of message dictionaries containing conversation history | ||
|
|
||
| Returns: | ||
| Agent response result | ||
| """ | ||
| result = agent.run(input=messages) | ||
| return result |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Confirm the expected handler return shape in bindufy and check other examples
rg -nP -C3 'agent\.run\(' examples/
rg -nP -C5 'handler_callable|handler\(' bindu/penguin/Repository: GetBindu/Bindu
Length of output: 19385
Handler return value doesn't match documented pattern.
The bindufy() function's own docstring (lines 661–663 in bindu/penguin/bindufy.py) demonstrates the expected handler pattern: extracting content via result.to_dict()["content"] before returning. Returning the raw RunResponse object contradicts this documented example and may cause serialization issues when the microservice responds to clients.
🛠️ Proposed fix
def handler(messages: list[dict[str, str]]):
"""Process messages and return agent response.
Args:
messages: List of message dictionaries containing conversation history
Returns:
- Agent response result
+ Agent response content as string
"""
result = agent.run(input=messages)
- return result
+ return result.to_dict()["content"]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def handler(messages: list[dict[str, str]]): | |
| """Process messages and return agent response. | |
| Args: | |
| messages: List of message dictionaries containing conversation history | |
| Returns: | |
| Agent response result | |
| """ | |
| result = agent.run(input=messages) | |
| return result | |
| def handler(messages: list[dict[str, str]]): | |
| """Process messages and return agent response. | |
| Args: | |
| messages: List of message dictionaries containing conversation history | |
| Returns: | |
| Agent response content as string | |
| """ | |
| result = agent.run(input=messages) | |
| return result.to_dict()["content"] |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@examples/beginner/motivational_agent.py` around lines 66 - 76, The handler
currently returns the raw RunResponse from agent.run, which contradicts the
bindufy() example that extracts and returns the serialized content; update
handler to call agent.run(input=messages), convert the result to a dict and
return only the "content" field (e.g., use result.to_dict()["content"]) so the
handler returns a JSON-serializable payload consistent with bindufy()'s
documented pattern; ensure you reference the handler function and agent.run and
handle missing keys or None safely before returning.
|
|
||
|
|
||
| # Bindu-fy it | ||
| bindufy(config, handler) |
There was a problem hiding this comment.
Restore if __name__ == "__main__": guard around bindufy(...).
Calling bindufy(config, handler) at module top level starts a blocking uvicorn server on mere import (e.g., tests, tooling, or from motivational_agent import agent). The previous version guarded this with a __main__ block; please restore that behavior.
🛠️ Proposed fix
-# Bindu-fy it
-bindufy(config, handler)
+# Bindu-fy it
+if __name__ == "__main__":
+ bindufy(config, handler)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| bindufy(config, handler) | |
| # Bindu-fy it | |
| if __name__ == "__main__": | |
| bindufy(config, handler) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@examples/beginner/motivational_agent.py` at line 80, The top-level call
bindufy(config, handler) starts a blocking server on import; move that call into
a main guard by wrapping it inside if __name__ == "__main__": so importing the
module won't start uvicorn—i.e., remove or comment the bare bindufy(config,
handler) and add a guarded call under if __name__ == "__main__": bindufy(config,
handler), ensuring config and handler remain in scope for the guarded
invocation.
Summary by CodeRabbit
New Features
Changes