## Weather Bot Agent Example with FunctionTool#119
## Weather Bot Agent Example with FunctionTool#119muscodev wants to merge 5 commits intojentic:mainfrom
Conversation
Question: Should FunctionTool be moved to core?Currently, I've implemented However, this functionality seems generally useful for the entire framework. Would it make sense to move it to Happy to refactor and create a separate PR for this if you think it's a good fit for the core library. |
|
Hi @rishikesh-jentic, |
|
@CodeRabbit review this PR |
|
✅ Actions performedReview triggered.
|
📝 WalkthroughWalkthroughThis pull request introduces a complete weather bot example application featuring an agent-based system with tool integration, supporting both CLI and web interfaces via FastAPI. It includes environment configuration, tool infrastructure for wrapping Python functions, OpenWeather API integration, and comprehensive tests. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Interface as Web/CLI Interface
participant Agent as Weather Agent
participant Reasoner as ReACT Reasoner
participant ToolProvider as Tool Provider
participant Weather as Weather Tools
participant LLM as LiteLLM
User->>Interface: Submit query/goal
Interface->>Agent: solve(goal)
Agent->>Reasoner: reason(goal)
loop Reasoning Loop
Reasoner->>LLM: Generate thought/action
LLM-->>Reasoner: Thought or Tool Use
alt Use Tool
Reasoner->>ToolProvider: execute(tool, params)
ToolProvider->>Weather: Call tool function
Weather-->>ToolProvider: Result
ToolProvider-->>Reasoner: Execution result
else Final Answer
Reasoner-->>Agent: Answer
end
end
Agent-->>Interface: ReasoningResult
Interface-->>User: Formatted response
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 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
Comment |
There was a problem hiding this comment.
Actionable comments posted: 15
🤖 Fix all issues with AI agents
In `@examples/weather_bot/app/agent.py`:
- Around line 12-13: The llm setup uses LiteLLM with max_tokens=50 which will
truncate weather answers; update the llm initialization (variable llm and
constructor LiteLLM) to use a much larger token budget (e.g., 200–500) or make
max_tokens configurable from an environment variable, and also pass the model
explicitly by reading an LLM_MODEL env var (or default) into the LiteLLM
constructor so the chosen model is used rather than relying on defaults.
In `@examples/weather_bot/app/bot.py`:
- Around line 213-220: The addMessage function is vulnerable because it sets
msg.innerHTML with unsanitized text; change the implementation to avoid
innerHTML by creating the bubble element via document.createElement('div') (or
similar) and set its textContent (or append a text node) for the message body
instead of interpolating into HTML, and ensure both the user-provided text and
any bot responses are treated as plain text (or passed through a sanitizer)
before inserting into the DOM; update references to msg.innerHTML and the bubble
creation in addMessage accordingly.
- Around line 40-42: The response string returned by the GET handler decorated
with `@app.get` in the function root uses a curly right single quotation mark;
replace that curly quote in the message "🤖 Hi! I’m WeatherBot. Use POST /ask
with {query: 'your question'}" with a standard ASCII apostrophe so the string
uses "I'm" and the inner quotes are standard single quotes for "your question";
update the literal in root to use straight ASCII quotes.
In `@examples/weather_bot/app/cli_bot.py`:
- Around line 38-52: The welcome print in main() contains grammatical and
typographical errors; update the string passed to print() (the welcome message
in main) to a clear, grammatically correct greeting such as a single sentence
that capitalizes properly, removes extra commas, and introduces the bot (e.g.,
"Hi! Welcome — I am WeatherBot. Ask me anything about the weather."). Ensure you
edit the print call inside main() that currently prints the malformed welcome
message.
In `@examples/weather_bot/app/tools_base.py`:
- Around line 117-120: The ValueError message in load (FunctionTool) has typos;
update the raise to use correct wording and punctuation (e.g., "function tool
doesn't have '{tool}' definition" or similar) so the message reads clearly;
change the string in the raise inside load that checks getattr(tool, 'id', None)
not in self._tools to the corrected text.
In `@examples/weather_bot/app/weather_tools.py`:
- Around line 63-64: Update the misleading error text in the status check where
resp and data are used: replace the "Failed to fetch weather" default message
with something accurate like "Failed to fetch coordinates" (keep using
data.get("message", "...") to surface API errors). Locate the conditional that
reads if resp.status_code != 200: return {"error": data.get("message", "Failed
to fetch weather")} and change the default string to reflect coordinates
fetching.
- Around line 52-54: The function get_coordinate_by_city currently has a
misplaced Annotated and an unused test parameter; remove the unused parameter
(test: bool = True) and apply the Annotated only to the city parameter with a
correct description (e.g., Annotated[str, "city name"]) so the signature becomes
a single-parameter async function; update any call sites that pass the
now-removed test argument accordingly.
- Around line 94-95: The error return uses a generic/incorrect default message;
change the default error text to accurately describe this operation (e.g.,
"Failed to fetch weather for provided coordinates" or similar) in the function
that contains the snippet (the same function pair as
get_coordinate_by_city—update the return in the block with resp.status_code !=
200 to use the new descriptive default message while still preferring
data.get("message", ...)). Ensure the message clearly mentions
weather-by-coordinates so it isn't misleading.
- Line 11: API_KEY is set from the environment but not validated, so it may be
None and cause silent auth failures; update the module to fail fast by
validating API_KEY after it’s loaded (the API_KEY symbol) and raise a clear
RuntimeError or log+exit if missing. Alternatively, if you need module import
without the key, add a helper like ensure_api_key_or_raise() and call it at the
start of each tool function that uses API_KEY (e.g., in any
get_weather()/fetch_forecast() functions) to perform the same check before
making API calls.
In `@examples/weather_bot/README.md`:
- Around line 113-121: The README contains a fenced code block without a
language specifier; update the block delimiter in examples/weather_bot/README.md
to include a language (e.g., change ``` to ```text or ```bash/```tree) so the
code fence declares its language for MD040 linting; edit the specific fenced
block that lists the project tree and replace its opening backticks with a
language-tagged opening backtick sequence.
- Line 124: The image reference in the README uses the misspelled directory
"screenshorts" instead of "screenshots"; update the image path in the Markdown
(the line containing "") to "" and verify the file exists at that corrected path,
also search the README for any other occurrences of "screenshorts" and correct
them to "screenshots".
- Around line 81-83: Remove the leading indentation before the command inside
the README's fenced code block so the line reads exactly `python -m app.cli_bot`
(no leading spaces) to avoid markdown rendering issues; update the code block
content where the command appears to ensure the backticks remain on their own
lines and the command line has no preceding whitespace.
- Around line 93-94: The README contains a code block line with a leading space
before the command "fastapi run app/bot.py"; remove the leading whitespace so
the command starts at column 0 (i.e., change " fastapi run app/bot.py" to
"fastapi run app/bot.py") to ensure correct rendering and copy-paste behavior in
the examples/weather_bot README.
- Around line 97-98: The README currently uses bare URLs on the lines starting
with "**Local**" and "**API Docs**"; replace those bare URLs with proper
Markdown link syntax by turning the labels into link text that points to their
respective URLs (e.g., use the "Local" label as the link text for
http://localhost:8000/chat and "API Docs" as the link text for
http://localhost:8000/docs) so the entries use [label](url) style links instead
of plain URLs.
- Line 4: The markdown image path contains a typo: update the markdown line
referencing the image (the token "! [bot](screenshorts/bot.png)" in README) to
use the correct folder name "screenshots" so it reads "!
[bot](screenshots/bot.png)" (or rename the directory to match the typo),
ensuring the image renders correctly.
🧹 Nitpick comments (8)
examples/weather_bot/requirements.txt (1)
1-4: Consider pinning dependency versions for reproducibility.Unpinned dependencies can lead to inconsistent behavior across environments. While acceptable for an example project, consider pinning at least major versions (e.g.,
httpx>=0.27,<1.0) to prevent unexpected breakages.Also,
pytestis a dev/test dependency—consider separating it into arequirements-dev.txtor using[dev]extras in apyproject.toml.Suggested improvements
-httpx -python-dotenv -pytest -fastapi[standard] +httpx>=0.27 +python-dotenv>=1.0 +fastapi[standard]>=0.115And create a separate
requirements-dev.txt:pytest>=8.0examples/weather_bot/.env_sample (1)
1-3: Use standard placeholder format for API keys.The placeholder text "replace with yours" contains spaces which could cause parsing issues if accidentally used. Consider using a more standard format.
Suggested format
-OPENWEATHER_API_KEY=replace with yours -GEMINI_API_KEY=replace with yours -OPENAI_API_KEY=replace with yours +OPENWEATHER_API_KEY=your_openweather_api_key_here +GEMINI_API_KEY=your_gemini_api_key_here +OPENAI_API_KEY=your_openai_api_key_hereexamples/weather_bot/tests/test_function_tool.py (1)
29-36: Test is functional but couples to internal structure.Accessing
provider._toolsdirectly works but ties the test to implementation details. Consider adding a public method likeget_tool(name)toFunctionToolProviderif this pattern is needed frequently.The exact string assertion on line 35 is somewhat brittle—if summary formatting changes, this test will break.
examples/weather_bot/app/cli_bot.py (2)
5-19: Simplify exception handling.The
except (EOFError, KeyboardInterrupt): raiseblock is redundant since exceptions propagate automatically. The static analyzer flagged this with TRY203.♻️ Suggested simplification
def read_user_goal(prompt: str = "🤖 Enter your goal: ") -> str: """Read a goal from user input via stdin.""" print(prompt, end="", flush=True) - try: - line = sys.stdin.readline() - if not line: # EOF - raise KeyboardInterrupt - - goal = line.strip() - if goal.lower() in {"bye", "quit", "exit", "q"}: - raise KeyboardInterrupt - - return goal - except (EOFError, KeyboardInterrupt): - raise + line = sys.stdin.readline() + if not line: # EOF + raise KeyboardInterrupt + + goal = line.strip() + if goal.lower() in {"bye", "quit", "exit", "q"}: + raise KeyboardInterrupt + + return goal
22-35: Consider adding type hint forresultparameter.The function works correctly with
ReasoningResult. Adding a type hint would improve clarity and enable better IDE support.♻️ Suggested type hint
+from agents.reasoner.base import ReasoningResult + -def print_result(result) -> None: +def print_result(result: ReasoningResult) -> None:examples/weather_bot/app/tools_base.py (1)
54-59: Addstacklevelto warning for better debugging.The warning will point to this internal line rather than the caller's registration site. Adding
stacklevel=2helps users identify which function lacks a docstring.♻️ Suggested fix
if not func.__doc__: warnings.warn( f"Functiontool '{func.__name__}' has no docstring. " - "Please add one — the first 2 lines will be used as summary." + "Please add one - the first 2 lines will be used as summary.", + stacklevel=2 )examples/weather_bot/app/bot.py (2)
29-37: Consider handlingresult.success == Falsecase.The endpoint always returns
final_answerregardless of success status. Failed queries might benefit from different handling (e.g., different HTTP status code or error field).♻️ Optional enhancement
`@app.post`("/ask") async def ask_bot(input: QueryRequest): query = BOT_PROMPT.format(user_query=input.query) result: ReasoningResult = await asyncio.to_thread( weather_agent.solve, query, ) - return {"response": str(result.final_answer)} + if result.success: + return {"response": str(result.final_answer)} + else: + return {"response": str(result.final_answer), "success": False}
47-48: Consider extracting HTML to a template file.The 200-line inline HTML string is harder to maintain and test. Consider using FastAPI's
Jinja2Templatesor serving a static HTML file.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
examples/weather_bot/screenshorts/bot.pngis excluded by!**/*.pngexamples/weather_bot/screenshorts/image.pngis excluded by!**/*.png
📒 Files selected for processing (10)
examples/weather_bot/.env_sampleexamples/weather_bot/README.mdexamples/weather_bot/app/__init__.pyexamples/weather_bot/app/agent.pyexamples/weather_bot/app/bot.pyexamples/weather_bot/app/cli_bot.pyexamples/weather_bot/app/tools_base.pyexamples/weather_bot/app/weather_tools.pyexamples/weather_bot/requirements.txtexamples/weather_bot/tests/test_function_tool.py
🧰 Additional context used
🧬 Code graph analysis (5)
examples/weather_bot/tests/test_function_tool.py (1)
examples/weather_bot/app/tools_base.py (3)
FunctionTool(47-84)FunctionToolProvider(87-135)tool(91-102)
examples/weather_bot/app/agent.py (5)
agents/standard_agent.py (1)
StandardAgent(36-149)agents/llm/litellm.py (1)
LiteLLM(10-142)agents/memory/dict_memory.py (1)
DictMemory(10-26)examples/discord/discord_agent.py (1)
reasoner(118-139)agents/reasoner/react.py (1)
ReACTReasoner(19-179)
examples/weather_bot/app/tools_base.py (1)
agents/tools/base.py (2)
ToolBase(7-30)JustInTimeToolingBase(32-48)
examples/weather_bot/app/bot.py (2)
agents/reasoner/base.py (1)
ReasoningResult(12-20)agents/standard_agent.py (1)
solve(88-125)
examples/weather_bot/app/cli_bot.py (1)
agents/standard_agent.py (1)
solve(88-125)
🪛 markdownlint-cli2 (0.18.1)
examples/weather_bot/README.md
97-97: Bare URL used
(MD034, no-bare-urls)
98-98: Bare URL used
(MD034, no-bare-urls)
113-113: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🪛 Ruff (0.14.11)
examples/weather_bot/app/weather_tools.py
53-53: Unused function argument: test
(ARG001)
examples/weather_bot/app/tools_base.py
55-55: No explicit stacklevel keyword argument found
Set stacklevel=2
(B028)
66-66: Docstring contains ambiguous – (EN DASH). Did you mean - (HYPHEN-MINUS)?
(RUF002)
119-119: Avoid specifying long messages outside the exception class
(TRY003)
examples/weather_bot/app/bot.py
42-42: String contains ambiguous ’ (RIGHT SINGLE QUOTATION MARK). Did you mean ``` (GRAVE ACCENT)?
(RUF001)
examples/weather_bot/app/cli_bot.py
11-11: Abstract raise to an inner function
(TRY301)
15-15: Abstract raise to an inner function
(TRY301)
17-17: Consider moving this statement to an else block
(TRY300)
18-19: Remove exception handler; error is immediately re-raised
(TRY203)
🔇 Additional comments (12)
examples/weather_bot/app/agent.py (1)
15-27: Agent wiring looks correct.The
StandardAgentis properly composed withLiteLLM,DictMemory,ReACTReasoner, and the weather tools. The component integration follows the expected patterns from the framework.examples/weather_bot/tests/test_function_tool.py (3)
1-25: Test setup and dummy functions look good.The dummy functions provide good coverage scenarios: sync with docstring, async with docstring, and sync without docstring. The type hints are properly defined for schema extraction testing.
90-95: Async test works but relies on internalasyncio.run.The test validates async execution correctly. Note that
provider.executeinternally callsasyncio.run(), which works here but would fail if called from within an already-running event loop. For more robust async testing, consider usingpytest-asynciowith@pytest.mark.asyncio.
98-102: Good coverage of error path.This test correctly validates that loading an unregistered tool raises
ValueError.examples/weather_bot/app/cli_bot.py (1)
1-2: LGTM!Imports are clean and minimal.
examples/weather_bot/app/weather_tools.py (1)
14-37: LGTM!The function correctly fetches weather data, handles errors, and returns a well-structured response.
examples/weather_bot/app/tools_base.py (4)
18-23: LGTM!The
parse_annotationhelper correctly extracts base type and metadata fromAnnotatedtypes.
26-44: LGTM!The
extract_param_infofunction correctly builds parameter metadata from function signatures and type hints.
61-84: LGTM!The
FunctionToolmethods correctly implement theToolBaseinterface, providing keywords, summary, details, and parameter schema extraction.
130-135: The current usage pattern is safe due toasyncio.to_thread(), but theexecute()method has a fragile API design.While the FastAPI integration in
bot.pycorrectly usesawait asyncio.to_thread(weather_agent.solve, query)to run the synchronous reasoning loop in a separate thread (avoiding event loop conflicts), the underlyingexecute()method remains error-prone. If integrated directly into an async context withoutasyncio.to_thread(), it would immediately fail withRuntimeError: This event loop is already running.Consider restructuring to provide a separate
async def execute_async()method that can be called from async contexts, or add robust loop detection to prevent misuse:async def execute_async(self, tool: FunctionTool, parameters: Dict[str, Any]) -> Any: """Async execution - use this when already in an async context.""" if inspect.iscoroutinefunction(tool.func): return await self._execute_async(tool, parameters) return self._execute_sync(tool, parameters)examples/weather_bot/app/bot.py (2)
1-9: LGTM!Imports and FastAPI app initialization are appropriate. Using
asyncio.to_threadfor the blockingsolve()call is the correct pattern.
11-22: BOT_PROMPT is actively used in the/askendpoint.The prompt is formatted with the user query and passed directly to
weather_agent.solve(). The current implementation wraps the user input with the prompt template before sending it to the agent, so the prompt is serving its intended purpose.Likely an incorrect or invalid review comment.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| # try changing to you own prefered model and add the API key in the .env file/ environment variable | ||
| llm = LiteLLM(max_tokens=50) |
There was a problem hiding this comment.
max_tokens=50 is likely too restrictive for weather responses.
A 50-token limit will severely truncate most LLM responses. Weather descriptions, forecasts, and conversational replies typically require 200-500+ tokens. This will cause incomplete or cut-off answers.
Additionally, the comment mentions changing the model, but no model parameter is passed to LiteLLM. Ensure LLM_MODEL is read from the environment or pass it explicitly.
Proposed fix
+import os
+
# try changing to you own prefered model and add the API key in the .env file/ environment variable
-llm = LiteLLM(max_tokens=50)
+llm = LiteLLM(model=os.getenv("LLM_MODEL"), max_tokens=1024)🤖 Prompt for AI Agents
In `@examples/weather_bot/app/agent.py` around lines 12 - 13, The llm setup uses
LiteLLM with max_tokens=50 which will truncate weather answers; update the llm
initialization (variable llm and constructor LiteLLM) to use a much larger token
budget (e.g., 200–500) or make max_tokens configurable from an environment
variable, and also pass the model explicitly by reading an LLM_MODEL env var (or
default) into the LiteLLM constructor so the chosen model is used rather than
relying on defaults.
| function addMessage(text, sender) { | ||
| const chat = document.getElementById('chat'); | ||
| const msg = document.createElement('div'); | ||
| msg.className = `message ${sender}`; | ||
| msg.innerHTML = `<div class="bubble">${text}</div>`; | ||
| chat.appendChild(msg); | ||
| chat.scrollTop = chat.scrollHeight; | ||
| } |
There was a problem hiding this comment.
XSS vulnerability: user and bot messages inserted via innerHTML without sanitization.
Both user input and bot responses are directly interpolated into HTML using innerHTML. If the bot response contains HTML or JavaScript (e.g., from a compromised API or unexpected data), it will execute in the user's browser.
🔒 Suggested fix using `textContent`
function addMessage(text, sender) {
const chat = document.getElementById('chat');
const msg = document.createElement('div');
msg.className = `message ${sender}`;
- msg.innerHTML = `<div class="bubble">${text}</div>`;
+ const bubble = document.createElement('div');
+ bubble.className = 'bubble';
+ bubble.textContent = text;
+ msg.appendChild(bubble);
chat.appendChild(msg);
chat.scrollTop = chat.scrollHeight;
}📝 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.
| function addMessage(text, sender) { | |
| const chat = document.getElementById('chat'); | |
| const msg = document.createElement('div'); | |
| msg.className = `message ${sender}`; | |
| msg.innerHTML = `<div class="bubble">${text}</div>`; | |
| chat.appendChild(msg); | |
| chat.scrollTop = chat.scrollHeight; | |
| } | |
| function addMessage(text, sender) { | |
| const chat = document.getElementById('chat'); | |
| const msg = document.createElement('div'); | |
| msg.className = `message ${sender}`; | |
| const bubble = document.createElement('div'); | |
| bubble.className = 'bubble'; | |
| bubble.textContent = text; | |
| msg.appendChild(bubble); | |
| chat.appendChild(msg); | |
| chat.scrollTop = chat.scrollHeight; | |
| } |
🤖 Prompt for AI Agents
In `@examples/weather_bot/app/bot.py` around lines 213 - 220, The addMessage
function is vulnerable because it sets msg.innerHTML with unsanitized text;
change the implementation to avoid innerHTML by creating the bubble element via
document.createElement('div') (or similar) and set its textContent (or append a
text node) for the message body instead of interpolating into HTML, and ensure
both the user-provided text and any bot responses are treated as plain text (or
passed through a sanitizer) before inserting into the DOM; update references to
msg.innerHTML and the bubble creation in addMessage accordingly.
| def main(): | ||
| # Step 4: Use your custom agent | ||
| print("HI!, Welcome , Iam WeatherBot please ask anything related to weather..") | ||
| while True: | ||
| try: | ||
| goal = read_user_goal() | ||
| if not goal: | ||
| continue | ||
|
|
||
| result = weather_agent.solve(goal) | ||
| print_result(result) | ||
|
|
||
| except KeyboardInterrupt: | ||
| print("\n🤖 Bye!") | ||
| break |
There was a problem hiding this comment.
Fix grammatical issues in welcome message.
The welcome message has typographical errors that affect user experience.
📝 Suggested fix
def main():
# Step 4: Use your custom agent
- print("HI!, Welcome , Iam WeatherBot please ask anything related to weather..")
+ print("Hi! Welcome, I am WeatherBot. Please ask anything related to weather.")
while True:🤖 Prompt for AI Agents
In `@examples/weather_bot/app/cli_bot.py` around lines 38 - 52, The welcome print
in main() contains grammatical and typographical errors; update the string
passed to print() (the welcome message in main) to a clear, grammatically
correct greeting such as a single sentence that capitalizes properly, removes
extra commas, and introduces the bot (e.g., "Hi! Welcome — I am WeatherBot. Ask
me anything about the weather."). Ensure you edit the print call inside main()
that currently prints the malformed welcome message.
| def load(self, tool: FunctionTool) -> FunctionTool: | ||
| if getattr(tool, 'id', None) not in self._tools: | ||
| raise ValueError(f"function tool dont have '{tool}' defenition") | ||
| return tool |
There was a problem hiding this comment.
Fix typos in error message.
The error message contains spelling errors: "dont have" → "doesn't have" and "defenition" → "definition".
📝 Suggested fix
def load(self, tool: FunctionTool) -> FunctionTool:
if getattr(tool, 'id', None) not in self._tools:
- raise ValueError(f"function tool dont have '{tool}' defenition")
+ raise ValueError(f"FunctionTool '{tool}' is not registered with this provider")
return tool📝 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 load(self, tool: FunctionTool) -> FunctionTool: | |
| if getattr(tool, 'id', None) not in self._tools: | |
| raise ValueError(f"function tool dont have '{tool}' defenition") | |
| return tool | |
| def load(self, tool: FunctionTool) -> FunctionTool: | |
| if getattr(tool, 'id', None) not in self._tools: | |
| raise ValueError(f"FunctionTool '{tool}' is not registered with this provider") | |
| return tool |
🧰 Tools
🪛 Ruff (0.14.11)
119-119: Avoid specifying long messages outside the exception class
(TRY003)
🤖 Prompt for AI Agents
In `@examples/weather_bot/app/tools_base.py` around lines 117 - 120, The
ValueError message in load (FunctionTool) has typos; update the raise to use
correct wording and punctuation (e.g., "function tool doesn't have '{tool}'
definition" or similar) so the message reads clearly; change the string in the
raise inside load that checks getattr(tool, 'id', None) not in self._tools to
the corrected text.
| python -m app.cli_bot | ||
| ``` | ||
|
|
There was a problem hiding this comment.
Remove leading whitespace from command.
The indentation before python -m app.cli_bot may cause rendering issues in some markdown viewers.
- python -m app.cli_bot
+python -m app.cli_bot🤖 Prompt for AI Agents
In `@examples/weather_bot/README.md` around lines 81 - 83, Remove the leading
indentation before the command inside the README's fenced code block so the line
reads exactly `python -m app.cli_bot` (no leading spaces) to avoid markdown
rendering issues; update the code block content where the command appears to
ensure the backticks remain on their own lines and the command line has no
preceding whitespace.
| fastapi run app/bot.py | ||
| ``` |
There was a problem hiding this comment.
Remove leading whitespace from command.
Same issue as above—leading whitespace before the command.
- fastapi run app/bot.py
+fastapi run app/bot.py📝 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.
| fastapi run app/bot.py | |
| ``` | |
| fastapi run app/bot.py |
🤖 Prompt for AI Agents
In `@examples/weather_bot/README.md` around lines 93 - 94, The README contains a
code block line with a leading space before the command "fastapi run
app/bot.py"; remove the leading whitespace so the command starts at column 0
(i.e., change " fastapi run app/bot.py" to "fastapi run app/bot.py") to
ensure correct rendering and copy-paste behavior in the examples/weather_bot
README.
| ``` | ||
|
|
||
|
|
||
|  No newline at end of file |
There was a problem hiding this comment.
Same typo in image path.
This image reference also uses "screenshorts" instead of "screenshots".
-
+📝 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.
|  | |
|  |
🤖 Prompt for AI Agents
In `@examples/weather_bot/README.md` at line 124, The image reference in the
README uses the misspelled directory "screenshorts" instead of "screenshots";
update the image path in the Markdown (the line containing "") to "" and
verify the file exists at that corrected path, also search the README for any
other occurrences of "screenshorts" and correct them to "screenshots".
There was a problem hiding this comment.
screenshorts -> screenshots
|
@muscodev Apologies for the very late review of the PR. I understand this was probably submitted as a Hacktoberfest submission but it took me a while to get back to PRs on the repo. The PR looks almost good to be merged. There are some minor comments from CodeRabbit which I think are valid (I have resolved minor nit picks from the tool). |
|
Can we merge it or , any updates are pending? |
|
@muscodev I see that there are some minor comments from myself and CodeRabbit that are yet to be resolved. I believe once they are resolved we should be good to merge. |

Added a weather bot agent example demonstrating the new
FunctionToolfeature for converting Python functions into agent tools.Related to #82
What's New
FunctionToolimplementation with automatic schema extraction from type hintsFiles Added
examples/weather_bot/- Complete weather bot exampleapp/tools_base.py- FunctionTool and FunctionToolProvider implementationapp/agent.py- CLI agent with tool integrationapp/bot.py- FastAPI web interfacetools creation
Implimented a decorator pattern
Summary by CodeRabbit
New Features
Documentation
Tests
✏️ Tip: You can customize this high-level summary in your review settings.