├── .gitignore ├── .python-version ├── LICENSE ├── README.md ├── agent-teams.py ├── chroma.sqlite └── chroma.sqlite3 ├── diagrams-src └── ai-agentsexcalidraw.excalidraw ├── finance-agent.py ├── image-agent.py ├── images ├── agent-teams.png ├── ai-agents-architecture.png ├── ai-agents-architecture.svg ├── finance-agent.png ├── image-agent.png └── ollama-agent.png ├── knowledge-agent.py ├── ollama-agent.py ├── pdfs └── How_I_Use_LLMs.pdf ├── ping-ollama.sh ├── pyproject.toml └── uv.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Python-generated files 2 | __pycache__/ 3 | *.py[oc] 4 | build/ 5 | dist/ 6 | wheels/ 7 | *.egg-info 8 | 9 | # Virtual environments 10 | .venv 11 | 12 | push.sh -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- 1 | 3.13.2 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2025] [Shreyash (WebDevCaptain)] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AI Agents using `agno` and Ollama 2 | 3 | Agents example list: 4 | 5 | 1. [Simple Ollama Agent](./ollama-agent.py) 6 | The first basic agent that uses Deepseek R1 (8B parameter) model. 7 | 8 | 2. [Finance Agent](./finance-agent.py) 9 | A simple finance agent using Yahoo Finance tool and Qwen 2.5 (1.5B parameter) model via Ollama. 10 | 11 | 3. [Team of Agents](./agent-teams.py) 12 | The team of agents uses DuckDuckGo search and Yahoo finance to summarize analyst recommendation and share latest news for a company given its stock ticker symbol. 13 | 14 | 4. [Image Agent](./image-agent.py) 15 | The image agent reads an image and uses Llama 3.2 vision model to describe the image. 16 | 17 | 5. [Knowledge Agent (WIP)](./knowledge-agent.py) 18 | The knowledge agent reads a PDF using PyPDF and uses ChromaDB (a vector database) to store embeddings (using Ollama embedder) and retrieve knowledge based on user queries. 19 | 20 | --- 21 | 22 | ## Basic Architecture 23 | 24 | ![Architecture](./images/ai-agents-architecture.svg) 25 | 26 | --- 27 | 28 | ## Requirements 29 | 30 | - [uv](https://github.com/astral-sh/uv) 31 | - [ollama](https://github.com/ollama) 32 | 33 | --- 34 | 35 | ## Commands 36 | 37 | 1. Initialize the project 38 | 39 | ```bash 40 | uv init 41 | ``` 42 | 43 | 2. Create a Python virtual environment using `uv` 44 | 45 | ```bash 46 | uv venv --python=3.13.2 47 | ``` 48 | 49 | 3. Install `agno` (previously phi data) and `ollama` 50 | 51 | ```bash 52 | uv add agno 53 | uv add ollama 54 | ``` 55 | 56 | 4. Pull Deepseek R1 (8B) and Qwen 2.5 (1.5B) models from Ollama registry 57 | 58 | ```bash 59 | ollama pull deepseek-r1:8b 60 | 61 | ollama pull qwen2.5:1.5b 62 | ``` 63 | 64 | 5. Run the simple ollama-agent app 65 | 66 | ```bash 67 | uv run ollama-agent.py 68 | ``` 69 | 70 | ![Simple Ollama Agent](./images/ollama-agent.png) 71 | 72 | --- 73 | 74 | ## Finance agent using Yahoo Finance tool 75 | 76 | - Run the finance-agent app 77 | 78 | ```bash 79 | uv run finance-agent.py 80 | ``` 81 | 82 | ![Finance Agent](./images/finance-agent.png) 83 | 84 | --- 85 | 86 | ## Team of Agents 87 | 88 | Finance agent works with Search agent to find the analyst recommendation for a company. 89 | 90 | ```bash 91 | uv run agent-teams.py 92 | ``` 93 | 94 | ![Team of Agents](./images/agent-teams.png) 95 | 96 | --- 97 | 98 | ## Image Agent 99 | 100 | Reads an image and uses Llama 3.2 vision model to describe the image. 101 | 102 | Model used: Llama 3.2 (11B parameter) 103 | 104 | ![Image Agent](./images/image-agent.png) 105 | 106 | --- 107 | 108 | ## Knowledge Agent (WIP) 109 | 110 | Reads a PDF using PyPDF and uses ChromaDB (a vector database) to store embeddings (using Ollama embedder) and retrieve knowledge based on user queries. 111 | 112 | Model used: Llama 3.2 (3B parameter) 113 | 114 | --- 115 | 116 | ## License 117 | 118 | This repository is licensed under the [MIT License](LICENSE). 119 | -------------------------------------------------------------------------------- /agent-teams.py: -------------------------------------------------------------------------------- 1 | from agno.agent import Agent 2 | from agno.models.ollama import Ollama 3 | from agno.tools.duckduckgo import DuckDuckGoTools 4 | from agno.tools.yfinance import YFinanceTools 5 | 6 | 7 | search_agent = Agent( 8 | name="Search Agent", 9 | role="Search the web", 10 | instructions=[ 11 | "Given a stock ticker symbol, retrieve news and company information from the web by using the DuckDuckGo search engine. Always include sources.", 12 | ], 13 | model=Ollama(id="qwen2.5:1.5b"), 14 | tools=[DuckDuckGoTools()], 15 | show_tool_calls=True, 16 | markdown=True, 17 | ) 18 | 19 | finance_agent = Agent( 20 | name="Finance Agent", 21 | role="Get financial data", 22 | instructions=[ 23 | "Given a stock ticker symbol, retrieve stock price, analyst recommendations, stock fundamentals, historical prices, and company information from Yahoo Finance." 24 | ], 25 | model=Ollama(id="qwen2.5:1.5b"), 26 | tools=[ 27 | YFinanceTools( 28 | stock_price=True, 29 | analyst_recommendations=True, 30 | stock_fundamentals=True, 31 | historical_prices=True, 32 | company_info=True, 33 | ) 34 | ], 35 | show_tool_calls=True, 36 | markdown=True, 37 | ) 38 | 39 | agent_team = Agent( 40 | model=Ollama(id="qwen2.5:1.5b"), 41 | team=[search_agent, finance_agent], 42 | description=[ 43 | "You are a team of agents, with the ability to search the web using DuckDuckGo and extract financial data from yahoo finance." 44 | ], 45 | instructions=[ 46 | "First, use the Search Agent to retrieve news and company information for the given stock ticker symbol. Then, use the Finance Agent to retrieve stock price, analyst recommendations, stock fundamentals, historical prices, and company information.", 47 | ], 48 | show_tool_calls=True, 49 | add_datetime_to_instructions=True, 50 | markdown=True, 51 | # debug_mode=True, 52 | ) 53 | 54 | agent_team.print_response( 55 | "Summarize analyst recommendations and share the latest news for Apple with stock ticker symbol of AAPL.", 56 | stream=True, 57 | ) 58 | -------------------------------------------------------------------------------- /chroma.sqlite/chroma.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebDevCaptain/agno-ai-agents/60cb36a311e349c70b418916fbb2e4c81d9f1c65/chroma.sqlite/chroma.sqlite3 -------------------------------------------------------------------------------- /diagrams-src/ai-agentsexcalidraw.excalidraw: -------------------------------------------------------------------------------- 1 | { 2 | "type": "excalidraw", 3 | "version": 2, 4 | "source": "https://excalidraw.com", 5 | "elements": [ 6 | { 7 | "id": "7lFFYbYAUjlshd8q_ocFr", 8 | "type": "rectangle", 9 | "x": 225.9375, 10 | "y": 358.16796875, 11 | "width": 257.7890625, 12 | "height": 137.3828125, 13 | "angle": 0, 14 | "strokeColor": "#1e1e1e", 15 | "backgroundColor": "#ffc9c9", 16 | "fillStyle": "solid", 17 | "strokeWidth": 2, 18 | "strokeStyle": "solid", 19 | "roughness": 1, 20 | "opacity": 100, 21 | "groupIds": [], 22 | "frameId": null, 23 | "index": "a0", 24 | "roundness": { 25 | "type": 3 26 | }, 27 | "seed": 1703586843, 28 | "version": 265, 29 | "versionNonce": 503138741, 30 | "isDeleted": false, 31 | "boundElements": [ 32 | { 33 | "type": "text", 34 | "id": "RJVwmI3RFsYGa73i231Bg" 35 | }, 36 | { 37 | "id": "n9Modq8EY3fdrPGtIM5t8", 38 | "type": "arrow" 39 | } 40 | ], 41 | "updated": 1741161226807, 42 | "link": null, 43 | "locked": false 44 | }, 45 | { 46 | "id": "RJVwmI3RFsYGa73i231Bg", 47 | "type": "text", 48 | "x": 269.6420669555664, 49 | "y": 409.359375, 50 | "width": 170.3799285888672, 51 | "height": 35, 52 | "angle": 0, 53 | "strokeColor": "#1e1e1e", 54 | "backgroundColor": "transparent", 55 | "fillStyle": "solid", 56 | "strokeWidth": 2, 57 | "strokeStyle": "solid", 58 | "roughness": 1, 59 | "opacity": 100, 60 | "groupIds": [], 61 | "frameId": null, 62 | "index": "a1", 63 | "roundness": null, 64 | "seed": 1140286229, 65 | "version": 213, 66 | "versionNonce": 819612571, 67 | "isDeleted": false, 68 | "boundElements": null, 69 | "updated": 1741160526923, 70 | "link": null, 71 | "locked": false, 72 | "text": "User Prompt", 73 | "fontSize": 28, 74 | "fontFamily": 5, 75 | "textAlign": "center", 76 | "verticalAlign": "middle", 77 | "containerId": "7lFFYbYAUjlshd8q_ocFr", 78 | "originalText": "User Prompt", 79 | "autoResize": true, 80 | "lineHeight": 1.25 81 | }, 82 | { 83 | "id": "KxKTnTPYtkUjsFt8D7fdK", 84 | "type": "rectangle", 85 | "x": 469.578125, 86 | "y": 41.6875, 87 | "width": 257.7890625, 88 | "height": 150, 89 | "angle": 0, 90 | "strokeColor": "#1e1e1e", 91 | "backgroundColor": "#96f2d7", 92 | "fillStyle": "solid", 93 | "strokeWidth": 2, 94 | "strokeStyle": "solid", 95 | "roughness": 1, 96 | "opacity": 100, 97 | "groupIds": [], 98 | "frameId": null, 99 | "index": "a2", 100 | "roundness": { 101 | "type": 3 102 | }, 103 | "seed": 568816213, 104 | "version": 392, 105 | "versionNonce": 960766069, 106 | "isDeleted": false, 107 | "boundElements": [ 108 | { 109 | "id": "M27LsSxLP2cOXepygv2wk", 110 | "type": "text" 111 | }, 112 | { 113 | "id": "0MkPoTLRjM_4NMSq48eCs", 114 | "type": "arrow" 115 | } 116 | ], 117 | "updated": 1741161233263, 118 | "link": null, 119 | "locked": false 120 | }, 121 | { 122 | "id": "M27LsSxLP2cOXepygv2wk", 123 | "type": "text", 124 | "x": 487.28470611572266, 125 | "y": 46.6875, 126 | "width": 222.3759002685547, 127 | "height": 140, 128 | "angle": 0, 129 | "strokeColor": "#1e1e1e", 130 | "backgroundColor": "transparent", 131 | "fillStyle": "solid", 132 | "strokeWidth": 2, 133 | "strokeStyle": "solid", 134 | "roughness": 1, 135 | "opacity": 100, 136 | "groupIds": [], 137 | "frameId": null, 138 | "index": "a3", 139 | "roundness": null, 140 | "seed": 1748978043, 141 | "version": 401, 142 | "versionNonce": 1890769429, 143 | "isDeleted": false, 144 | "boundElements": null, 145 | "updated": 1741160837658, 146 | "link": null, 147 | "locked": false, 148 | "text": "Data Sources\n(could be\nembeddings from\na vector DB)", 149 | "fontSize": 28, 150 | "fontFamily": 5, 151 | "textAlign": "center", 152 | "verticalAlign": "middle", 153 | "containerId": "KxKTnTPYtkUjsFt8D7fdK", 154 | "originalText": "Data Sources\n(could be embeddings from a vector DB)", 155 | "autoResize": true, 156 | "lineHeight": 1.25 157 | }, 158 | { 159 | "id": "RjDEa2H5OJsqbNirZbQOK", 160 | "type": "ellipse", 161 | "x": 707.8515625, 162 | "y": 437.0859375, 163 | "width": 243.85937499999997, 164 | "height": 243.93359375000003, 165 | "angle": 0, 166 | "strokeColor": "#1e1e1e", 167 | "backgroundColor": "#e9ecef", 168 | "fillStyle": "solid", 169 | "strokeWidth": 2, 170 | "strokeStyle": "solid", 171 | "roughness": 1, 172 | "opacity": 100, 173 | "groupIds": [], 174 | "frameId": null, 175 | "index": "a4", 176 | "roundness": { 177 | "type": 2 178 | }, 179 | "seed": 328815861, 180 | "version": 987, 181 | "versionNonce": 1571299381, 182 | "isDeleted": false, 183 | "boundElements": [ 184 | { 185 | "type": "text", 186 | "id": "bFd_eTxNhunR0Vtc7fkz_" 187 | }, 188 | { 189 | "id": "n9Modq8EY3fdrPGtIM5t8", 190 | "type": "arrow" 191 | }, 192 | { 193 | "id": "0MkPoTLRjM_4NMSq48eCs", 194 | "type": "arrow" 195 | }, 196 | { 197 | "id": "44IZauDQ5pdZtyFWrLogN", 198 | "type": "arrow" 199 | }, 200 | { 201 | "id": "zhJplVmZj6fRqR3J0sSMV", 202 | "type": "arrow" 203 | }, 204 | { 205 | "id": "kgfp4FhAmz8LdiPokmJf3", 206 | "type": "arrow" 207 | }, 208 | { 209 | "id": "Xd6kUkVWiWc2uqTLBRzhq", 210 | "type": "arrow" 211 | }, 212 | { 213 | "id": "vb7ledYlHl4C_XRcM9Z6t", 214 | "type": "arrow" 215 | }, 216 | { 217 | "id": "YBrrCS4RPtGXsCY-qFzLi", 218 | "type": "arrow" 219 | } 220 | ], 221 | "updated": 1741161384346, 222 | "link": null, 223 | "locked": false 224 | }, 225 | { 226 | "id": "bFd_eTxNhunR0Vtc7fkz_", 227 | "type": "text", 228 | "x": 758.9059668976294, 229 | "y": 523.8091852250852, 230 | "width": 141.31594848632812, 231 | "height": 70, 232 | "angle": 0, 233 | "strokeColor": "#1e1e1e", 234 | "backgroundColor": "transparent", 235 | "fillStyle": "solid", 236 | "strokeWidth": 2, 237 | "strokeStyle": "solid", 238 | "roughness": 1, 239 | "opacity": 100, 240 | "groupIds": [], 241 | "frameId": null, 242 | "index": "a5", 243 | "roundness": null, 244 | "seed": 1994278075, 245 | "version": 562, 246 | "versionNonce": 609262811, 247 | "isDeleted": false, 248 | "boundElements": null, 249 | "updated": 1741161128620, 250 | "link": null, 251 | "locked": false, 252 | "text": "Agent\nFramework", 253 | "fontSize": 28, 254 | "fontFamily": 5, 255 | "textAlign": "center", 256 | "verticalAlign": "middle", 257 | "containerId": "RjDEa2H5OJsqbNirZbQOK", 258 | "originalText": "Agent Framework", 259 | "autoResize": true, 260 | "lineHeight": 1.25 261 | }, 262 | { 263 | "id": "RcJM8Et9mDGRNHb6J-Scj", 264 | "type": "diamond", 265 | "x": 983.29296875, 266 | "y": 23.8203125, 267 | "width": 340.0859375, 268 | "height": 160, 269 | "angle": 0, 270 | "strokeColor": "#1e1e1e", 271 | "backgroundColor": "#a5d8ff", 272 | "fillStyle": "solid", 273 | "strokeWidth": 2, 274 | "strokeStyle": "solid", 275 | "roughness": 1, 276 | "opacity": 100, 277 | "groupIds": [], 278 | "frameId": null, 279 | "index": "a6", 280 | "roundness": { 281 | "type": 2 282 | }, 283 | "seed": 1656632725, 284 | "version": 299, 285 | "versionNonce": 555927541, 286 | "isDeleted": false, 287 | "boundElements": [ 288 | { 289 | "type": "text", 290 | "id": "Bb47BjwszP9nnY9YG2VSp" 291 | }, 292 | { 293 | "id": "kgfp4FhAmz8LdiPokmJf3", 294 | "type": "arrow" 295 | }, 296 | { 297 | "id": "Xd6kUkVWiWc2uqTLBRzhq", 298 | "type": "arrow" 299 | } 300 | ], 301 | "updated": 1741161198584, 302 | "link": null, 303 | "locked": false 304 | }, 305 | { 306 | "id": "Bb47BjwszP9nnY9YG2VSp", 307 | "type": "text", 308 | "x": 1107.0444717407227, 309 | "y": 68.8203125, 310 | "width": 92.53996276855469, 311 | "height": 70, 312 | "angle": 0, 313 | "strokeColor": "#1e1e1e", 314 | "backgroundColor": "transparent", 315 | "fillStyle": "solid", 316 | "strokeWidth": 2, 317 | "strokeStyle": "solid", 318 | "roughness": 1, 319 | "opacity": 100, 320 | "groupIds": [], 321 | "frameId": null, 322 | "index": "a7", 323 | "roundness": null, 324 | "seed": 331804469, 325 | "version": 163, 326 | "versionNonce": 1398274395, 327 | "isDeleted": false, 328 | "boundElements": null, 329 | "updated": 1741160643200, 330 | "link": null, 331 | "locked": false, 332 | "text": "Tools\n(APIs)", 333 | "fontSize": 28, 334 | "fontFamily": 5, 335 | "textAlign": "center", 336 | "verticalAlign": "middle", 337 | "containerId": "RcJM8Et9mDGRNHb6J-Scj", 338 | "originalText": "Tools (APIs)", 339 | "autoResize": true, 340 | "lineHeight": 1.25 341 | }, 342 | { 343 | "id": "-k91PM7OeuHp2iY1FTEzJ", 344 | "type": "rectangle", 345 | "x": 1325.515625, 346 | "y": 383.39453125, 347 | "width": 344.62109375000006, 348 | "height": 420.61328125000006, 349 | "angle": 0, 350 | "strokeColor": "#1e1e1e", 351 | "backgroundColor": "#ffec99", 352 | "fillStyle": "solid", 353 | "strokeWidth": 2, 354 | "strokeStyle": "solid", 355 | "roughness": 1, 356 | "opacity": 100, 357 | "groupIds": [], 358 | "frameId": null, 359 | "index": "a8", 360 | "roundness": { 361 | "type": 3 362 | }, 363 | "seed": 1260546901, 364 | "version": 369, 365 | "versionNonce": 143276405, 366 | "isDeleted": false, 367 | "boundElements": [ 368 | { 369 | "type": "text", 370 | "id": "GhIKTHmVC7JsqH3k3P0MD" 371 | }, 372 | { 373 | "id": "44IZauDQ5pdZtyFWrLogN", 374 | "type": "arrow" 375 | }, 376 | { 377 | "id": "zhJplVmZj6fRqR3J0sSMV", 378 | "type": "arrow" 379 | }, 380 | { 381 | "id": "vb7ledYlHl4C_XRcM9Z6t", 382 | "type": "arrow" 383 | }, 384 | { 385 | "id": "YBrrCS4RPtGXsCY-qFzLi", 386 | "type": "arrow" 387 | } 388 | ], 389 | "updated": 1741161384346, 390 | "link": null, 391 | "locked": false 392 | }, 393 | { 394 | "id": "GhIKTHmVC7JsqH3k3P0MD", 395 | "type": "text", 396 | "x": 1347.5922241210938, 397 | "y": 558.701171875, 398 | "width": 300.4678955078125, 399 | "height": 70, 400 | "angle": 0, 401 | "strokeColor": "#1971c2", 402 | "backgroundColor": "transparent", 403 | "fillStyle": "solid", 404 | "strokeWidth": 2, 405 | "strokeStyle": "solid", 406 | "roughness": 1, 407 | "opacity": 100, 408 | "groupIds": [], 409 | "frameId": null, 410 | "index": "a9", 411 | "roundness": null, 412 | "seed": 1215997403, 413 | "version": 304, 414 | "versionNonce": 626094069, 415 | "isDeleted": false, 416 | "boundElements": null, 417 | "updated": 1741161110639, 418 | "link": null, 419 | "locked": false, 420 | "text": "LLM (Llama, Deepseek,\nOpenAI models)", 421 | "fontSize": 28, 422 | "fontFamily": 5, 423 | "textAlign": "center", 424 | "verticalAlign": "middle", 425 | "containerId": "-k91PM7OeuHp2iY1FTEzJ", 426 | "originalText": "LLM (Llama, Deepseek, OpenAI models)", 427 | "autoResize": true, 428 | "lineHeight": 1.25 429 | }, 430 | { 431 | "id": "n9Modq8EY3fdrPGtIM5t8", 432 | "type": "arrow", 433 | "x": 490.5845857934269, 434 | "y": 458.6569665366049, 435 | "width": 208.26669429496445, 436 | "height": 87.33696753467444, 437 | "angle": 0, 438 | "strokeColor": "#2f9e44", 439 | "backgroundColor": "transparent", 440 | "fillStyle": "solid", 441 | "strokeWidth": 2, 442 | "strokeStyle": "solid", 443 | "roughness": 1, 444 | "opacity": 100, 445 | "groupIds": [], 446 | "frameId": null, 447 | "index": "aA", 448 | "roundness": { 449 | "type": 2 450 | }, 451 | "seed": 425967029, 452 | "version": 385, 453 | "versionNonce": 1467894139, 454 | "isDeleted": false, 455 | "boundElements": [ 456 | { 457 | "type": "text", 458 | "id": "tUZAqa7oYM5Nnfv0RqGYE" 459 | } 460 | ], 461 | "updated": 1741161128620, 462 | "link": null, 463 | "locked": false, 464 | "points": [ 465 | [ 466 | 0, 467 | 0 468 | ], 469 | [ 470 | 208.26669429496445, 471 | 87.33696753467444 472 | ] 473 | ], 474 | "lastCommittedPoint": null, 475 | "startBinding": { 476 | "elementId": "7lFFYbYAUjlshd8q_ocFr", 477 | "focus": -0.20651328588427847, 478 | "gap": 7.859375 479 | }, 480 | "endBinding": { 481 | "elementId": "RjDEa2H5OJsqbNirZbQOK", 482 | "focus": -0.24139577841372423, 483 | "gap": 9.649540102436813 484 | }, 485 | "startArrowhead": null, 486 | "endArrowhead": "arrow", 487 | "elbowed": false 488 | }, 489 | { 490 | "id": "tUZAqa7oYM5Nnfv0RqGYE", 491 | "type": "text", 492 | "x": 627.4028625488281, 493 | "y": 432.365234375, 494 | "width": 11.95599365234375, 495 | "height": 35, 496 | "angle": 0, 497 | "strokeColor": "#2f9e44", 498 | "backgroundColor": "transparent", 499 | "fillStyle": "solid", 500 | "strokeWidth": 2, 501 | "strokeStyle": "solid", 502 | "roughness": 1, 503 | "opacity": 100, 504 | "groupIds": [], 505 | "frameId": null, 506 | "index": "aAV", 507 | "roundness": null, 508 | "seed": 1009517813, 509 | "version": 4, 510 | "versionNonce": 602303259, 511 | "isDeleted": false, 512 | "boundElements": null, 513 | "updated": 1741160748408, 514 | "link": null, 515 | "locked": false, 516 | "text": "1", 517 | "fontSize": 28, 518 | "fontFamily": 5, 519 | "textAlign": "center", 520 | "verticalAlign": "middle", 521 | "containerId": "n9Modq8EY3fdrPGtIM5t8", 522 | "originalText": "1", 523 | "autoResize": true, 524 | "lineHeight": 1.25 525 | }, 526 | { 527 | "id": "0MkPoTLRjM_4NMSq48eCs", 528 | "type": "arrow", 529 | "x": 566.3083154051787, 530 | "y": 192.3313016220662, 531 | "width": 199.6096801311063, 532 | "height": 256.40057274073183, 533 | "angle": 0, 534 | "strokeColor": "#e03131", 535 | "backgroundColor": "transparent", 536 | "fillStyle": "solid", 537 | "strokeWidth": 2, 538 | "strokeStyle": "solid", 539 | "roughness": 1, 540 | "opacity": 100, 541 | "groupIds": [], 542 | "frameId": null, 543 | "index": "aC", 544 | "roundness": { 545 | "type": 2 546 | }, 547 | "seed": 1333707829, 548 | "version": 388, 549 | "versionNonce": 2106417691, 550 | "isDeleted": false, 551 | "boundElements": [ 552 | { 553 | "type": "text", 554 | "id": "v2WW5osaqKdB24_tzlZ7p" 555 | } 556 | ], 557 | "updated": 1741161128620, 558 | "link": null, 559 | "locked": false, 560 | "points": [ 561 | [ 562 | 0, 563 | 0 564 | ], 565 | [ 566 | 199.6096801311063, 567 | 256.40057274073183 568 | ] 569 | ], 570 | "lastCommittedPoint": null, 571 | "startBinding": { 572 | "elementId": "KxKTnTPYtkUjsFt8D7fdK", 573 | "focus": 0.4859486684156935, 574 | "gap": 1.2734375 575 | }, 576 | "endBinding": { 577 | "elementId": "RjDEa2H5OJsqbNirZbQOK", 578 | "focus": 0.10160451632540532, 579 | "gap": 5.514899608580253 580 | }, 581 | "startArrowhead": null, 582 | "endArrowhead": "arrow", 583 | "elbowed": false 584 | }, 585 | { 586 | "id": "v2WW5osaqKdB24_tzlZ7p", 587 | "type": "text", 588 | "x": 745.4265670776367, 589 | "y": 249.162109375, 590 | "width": 19.599990844726562, 591 | "height": 35, 592 | "angle": 0, 593 | "strokeColor": "#e03131", 594 | "backgroundColor": "transparent", 595 | "fillStyle": "solid", 596 | "strokeWidth": 2, 597 | "strokeStyle": "solid", 598 | "roughness": 1, 599 | "opacity": 100, 600 | "groupIds": [], 601 | "frameId": null, 602 | "index": "aD", 603 | "roundness": null, 604 | "seed": 490850837, 605 | "version": 4, 606 | "versionNonce": 1391363451, 607 | "isDeleted": false, 608 | "boundElements": null, 609 | "updated": 1741160782711, 610 | "link": null, 611 | "locked": false, 612 | "text": "2", 613 | "fontSize": 28, 614 | "fontFamily": 5, 615 | "textAlign": "center", 616 | "verticalAlign": "middle", 617 | "containerId": "0MkPoTLRjM_4NMSq48eCs", 618 | "originalText": "2", 619 | "autoResize": true, 620 | "lineHeight": 1.25 621 | }, 622 | { 623 | "id": "44IZauDQ5pdZtyFWrLogN", 624 | "type": "arrow", 625 | "x": 948.9633731819908, 626 | "y": 557.2298393475994, 627 | "width": 372.041847180451, 628 | "height": 0.4769203158203936, 629 | "angle": 0, 630 | "strokeColor": "#f08c00", 631 | "backgroundColor": "transparent", 632 | "fillStyle": "solid", 633 | "strokeWidth": 2, 634 | "strokeStyle": "solid", 635 | "roughness": 1, 636 | "opacity": 100, 637 | "groupIds": [], 638 | "frameId": null, 639 | "index": "aE", 640 | "roundness": { 641 | "type": 2 642 | }, 643 | "seed": 1627497147, 644 | "version": 619, 645 | "versionNonce": 202776405, 646 | "isDeleted": false, 647 | "boundElements": [ 648 | { 649 | "type": "text", 650 | "id": "3ODKoG4CJ4RD1L4lyYno1" 651 | } 652 | ], 653 | "updated": 1741161323217, 654 | "link": null, 655 | "locked": false, 656 | "points": [ 657 | [ 658 | 0, 659 | 0 660 | ], 661 | [ 662 | 372.041847180451, 663 | 0.4769203158203936 664 | ] 665 | ], 666 | "lastCommittedPoint": null, 667 | "startBinding": { 668 | "elementId": "RjDEa2H5OJsqbNirZbQOK", 669 | "focus": -0.01617773029306769, 670 | "gap": 2.733633184633785 671 | }, 672 | "endBinding": { 673 | "elementId": "-k91PM7OeuHp2iY1FTEzJ", 674 | "focus": 0.16989581489301428, 675 | "gap": 4.5104046375581675 676 | }, 677 | "startArrowhead": null, 678 | "endArrowhead": "arrow", 679 | "elbowed": false 680 | }, 681 | { 682 | "id": "3ODKoG4CJ4RD1L4lyYno1", 683 | "type": "text", 684 | "x": 1155.2359646280727, 685 | "y": 533.3602138991068, 686 | "width": 17.02398681640625, 687 | "height": 35, 688 | "angle": 0, 689 | "strokeColor": "#f08c00", 690 | "backgroundColor": "transparent", 691 | "fillStyle": "solid", 692 | "strokeWidth": 2, 693 | "strokeStyle": "solid", 694 | "roughness": 1, 695 | "opacity": 100, 696 | "groupIds": [], 697 | "frameId": null, 698 | "index": "aF", 699 | "roundness": null, 700 | "seed": 932654459, 701 | "version": 5, 702 | "versionNonce": 312190331, 703 | "isDeleted": false, 704 | "boundElements": null, 705 | "updated": 1741160878275, 706 | "link": null, 707 | "locked": false, 708 | "text": "3", 709 | "fontSize": 28, 710 | "fontFamily": 5, 711 | "textAlign": "center", 712 | "verticalAlign": "middle", 713 | "containerId": "44IZauDQ5pdZtyFWrLogN", 714 | "originalText": "3", 715 | "autoResize": true, 716 | "lineHeight": 1.25 717 | }, 718 | { 719 | "id": "zhJplVmZj6fRqR3J0sSMV", 720 | "type": "arrow", 721 | "x": 1318.7798973634458, 722 | "y": 523.2790496120313, 723 | "width": 370.78007281756277, 724 | "height": 3.0145911975921535, 725 | "angle": 0, 726 | "strokeColor": "#9c36b5", 727 | "backgroundColor": "transparent", 728 | "fillStyle": "solid", 729 | "strokeWidth": 2, 730 | "strokeStyle": "solid", 731 | "roughness": 1, 732 | "opacity": 100, 733 | "groupIds": [], 734 | "frameId": null, 735 | "index": "aG", 736 | "roundness": { 737 | "type": 2 738 | }, 739 | "seed": 435504277, 740 | "version": 385, 741 | "versionNonce": 278894005, 742 | "isDeleted": false, 743 | "boundElements": [ 744 | { 745 | "type": "text", 746 | "id": "ZazA0w2bKkvtDpy3cSaHs" 747 | } 748 | ], 749 | "updated": 1741161313857, 750 | "link": null, 751 | "locked": false, 752 | "points": [ 753 | [ 754 | 0, 755 | 0 756 | ], 757 | [ 758 | -370.78007281756277, 759 | -3.0145911975921535 760 | ] 761 | ], 762 | "lastCommittedPoint": null, 763 | "startBinding": { 764 | "elementId": "-k91PM7OeuHp2iY1FTEzJ", 765 | "focus": 0.32576254099658264, 766 | "gap": 6.735727636554202 767 | }, 768 | "endBinding": { 769 | "elementId": "RjDEa2H5OJsqbNirZbQOK", 770 | "focus": -0.3232762173093418, 771 | "gap": 2.486005273506634 772 | }, 773 | "startArrowhead": null, 774 | "endArrowhead": "arrow", 775 | "elbowed": false 776 | }, 777 | { 778 | "id": "ZazA0w2bKkvtDpy3cSaHs", 779 | "type": "text", 780 | "x": 1159.3139114379883, 781 | "y": 478.388671875, 782 | "width": 16.379989624023438, 783 | "height": 35, 784 | "angle": 0, 785 | "strokeColor": "#9c36b5", 786 | "backgroundColor": "transparent", 787 | "fillStyle": "solid", 788 | "strokeWidth": 2, 789 | "strokeStyle": "solid", 790 | "roughness": 1, 791 | "opacity": 100, 792 | "groupIds": [], 793 | "frameId": null, 794 | "index": "aGV", 795 | "roundness": null, 796 | "seed": 658482427, 797 | "version": 6, 798 | "versionNonce": 1591370709, 799 | "isDeleted": false, 800 | "boundElements": null, 801 | "updated": 1741160942367, 802 | "link": null, 803 | "locked": false, 804 | "text": "4", 805 | "fontSize": 28, 806 | "fontFamily": 5, 807 | "textAlign": "center", 808 | "verticalAlign": "middle", 809 | "containerId": "zhJplVmZj6fRqR3J0sSMV", 810 | "originalText": "4", 811 | "autoResize": true, 812 | "lineHeight": 1.25 813 | }, 814 | { 815 | "id": "o9MfsKGSRNycZDG6xwmTL", 816 | "type": "text", 817 | "x": 1029.004486911823, 818 | "y": 481.03903873270207, 819 | "width": 203.95989990234375, 820 | "height": 25, 821 | "angle": 0.014485252704434792, 822 | "strokeColor": "#099268", 823 | "backgroundColor": "transparent", 824 | "fillStyle": "solid", 825 | "strokeWidth": 2, 826 | "strokeStyle": "solid", 827 | "roughness": 1, 828 | "opacity": 100, 829 | "groupIds": [], 830 | "frameId": null, 831 | "index": "aJ", 832 | "roundness": null, 833 | "seed": 890576219, 834 | "version": 420, 835 | "versionNonce": 1028247701, 836 | "isDeleted": false, 837 | "boundElements": null, 838 | "updated": 1741161316169, 839 | "link": null, 840 | "locked": false, 841 | "text": "I want to use a tool", 842 | "fontSize": 20, 843 | "fontFamily": 5, 844 | "textAlign": "left", 845 | "verticalAlign": "top", 846 | "containerId": null, 847 | "originalText": "I want to use a tool", 848 | "autoResize": true, 849 | "lineHeight": 1.25 850 | }, 851 | { 852 | "id": "kgfp4FhAmz8LdiPokmJf3", 853 | "type": "arrow", 854 | "x": 836.4008682171986, 855 | "y": 436.26435003653535, 856 | "width": 194.86340084276685, 857 | "height": 308.2519209536815, 858 | "angle": 0, 859 | "strokeColor": "#9c36b5", 860 | "backgroundColor": "transparent", 861 | "fillStyle": "solid", 862 | "strokeWidth": 2, 863 | "strokeStyle": "solid", 864 | "roughness": 1, 865 | "opacity": 100, 866 | "groupIds": [], 867 | "frameId": null, 868 | "index": "aK", 869 | "roundness": { 870 | "type": 2 871 | }, 872 | "seed": 1189432795, 873 | "version": 167, 874 | "versionNonce": 1491874811, 875 | "isDeleted": false, 876 | "boundElements": [ 877 | { 878 | "type": "text", 879 | "id": "P9vuP4-RROruyLf8aaq51" 880 | } 881 | ], 882 | "updated": 1741161128620, 883 | "link": null, 884 | "locked": false, 885 | "points": [ 886 | [ 887 | 0, 888 | 0 889 | ], 890 | [ 891 | 194.86340084276685, 892 | -308.2519209536815 893 | ] 894 | ], 895 | "lastCommittedPoint": null, 896 | "startBinding": { 897 | "elementId": "RjDEa2H5OJsqbNirZbQOK", 898 | "focus": -0.3567584075479287, 899 | "gap": 1 900 | }, 901 | "endBinding": { 902 | "elementId": "RcJM8Et9mDGRNHb6J-Scj", 903 | "focus": 0.628061363807714, 904 | "gap": 1.1915795027880878 905 | }, 906 | "startArrowhead": null, 907 | "endArrowhead": "arrow", 908 | "elbowed": false 909 | }, 910 | { 911 | "id": "P9vuP4-RROruyLf8aaq51", 912 | "type": "text", 913 | "x": 972.8493041992188, 914 | "y": 252.87890625, 915 | "width": 12.3599853515625, 916 | "height": 25, 917 | "angle": 0, 918 | "strokeColor": "#9c36b5", 919 | "backgroundColor": "transparent", 920 | "fillStyle": "solid", 921 | "strokeWidth": 2, 922 | "strokeStyle": "solid", 923 | "roughness": 1, 924 | "opacity": 100, 925 | "groupIds": [], 926 | "frameId": null, 927 | "index": "aL", 928 | "roundness": null, 929 | "seed": 725527355, 930 | "version": 3, 931 | "versionNonce": 2129170715, 932 | "isDeleted": false, 933 | "boundElements": null, 934 | "updated": 1741160978123, 935 | "link": null, 936 | "locked": false, 937 | "text": "5", 938 | "fontSize": 20, 939 | "fontFamily": 5, 940 | "textAlign": "center", 941 | "verticalAlign": "middle", 942 | "containerId": "kgfp4FhAmz8LdiPokmJf3", 943 | "originalText": "5", 944 | "autoResize": true, 945 | "lineHeight": 1.25 946 | }, 947 | { 948 | "id": "Xd6kUkVWiWc2uqTLBRzhq", 949 | "type": "arrow", 950 | "x": 1110.5085878663083, 951 | "y": 169.15288305259358, 952 | "width": 199.6163686659046, 953 | "height": 291.79008643186114, 954 | "angle": 0, 955 | "strokeColor": "#0c8599", 956 | "backgroundColor": "transparent", 957 | "fillStyle": "solid", 958 | "strokeWidth": 2, 959 | "strokeStyle": "solid", 960 | "roughness": 1, 961 | "opacity": 100, 962 | "groupIds": [], 963 | "frameId": null, 964 | "index": "aM", 965 | "roundness": { 966 | "type": 2 967 | }, 968 | "seed": 351026741, 969 | "version": 206, 970 | "versionNonce": 517602459, 971 | "isDeleted": false, 972 | "boundElements": [ 973 | { 974 | "type": "text", 975 | "id": "psmN_Ep4KUiZFJNnMgVxY" 976 | } 977 | ], 978 | "updated": 1741161128621, 979 | "link": null, 980 | "locked": false, 981 | "points": [ 982 | [ 983 | 0, 984 | 0 985 | ], 986 | [ 987 | -199.6163686659046, 988 | 291.79008643186114 989 | ] 990 | ], 991 | "lastCommittedPoint": null, 992 | "startBinding": { 993 | "elementId": "RcJM8Et9mDGRNHb6J-Scj", 994 | "focus": -0.01063381588494243, 995 | "gap": 6.121565499308501 996 | }, 997 | "endBinding": { 998 | "elementId": "RjDEa2H5OJsqbNirZbQOK", 999 | "focus": 0.0680562626486383, 1000 | "gap": 5.345230462439143 1001 | }, 1002 | "startArrowhead": null, 1003 | "endArrowhead": "arrow", 1004 | "elbowed": false 1005 | }, 1006 | { 1007 | "id": "psmN_Ep4KUiZFJNnMgVxY", 1008 | "type": "text", 1009 | "x": 1034.1058654785156, 1010 | "y": 277.669921875, 1011 | "width": 12.79998779296875, 1012 | "height": 25, 1013 | "angle": 0, 1014 | "strokeColor": "#0c8599", 1015 | "backgroundColor": "transparent", 1016 | "fillStyle": "solid", 1017 | "strokeWidth": 2, 1018 | "strokeStyle": "solid", 1019 | "roughness": 1, 1020 | "opacity": 100, 1021 | "groupIds": [], 1022 | "frameId": null, 1023 | "index": "aN", 1024 | "roundness": null, 1025 | "seed": 1628929595, 1026 | "version": 12, 1027 | "versionNonce": 2004119899, 1028 | "isDeleted": false, 1029 | "boundElements": null, 1030 | "updated": 1741161093471, 1031 | "link": null, 1032 | "locked": false, 1033 | "text": "6", 1034 | "fontSize": 20, 1035 | "fontFamily": 5, 1036 | "textAlign": "center", 1037 | "verticalAlign": "middle", 1038 | "containerId": "Xd6kUkVWiWc2uqTLBRzhq", 1039 | "originalText": "6", 1040 | "autoResize": true, 1041 | "lineHeight": 1.25 1042 | }, 1043 | { 1044 | "id": "i3iW332bTDQhQujJZK0kV", 1045 | "type": "text", 1046 | "x": 1076.2272602653502, 1047 | "y": 235.1015625, 1048 | "width": 448.32495944976836, 1049 | "height": 75, 1050 | "angle": 0, 1051 | "strokeColor": "#0c8599", 1052 | "backgroundColor": "transparent", 1053 | "fillStyle": "solid", 1054 | "strokeWidth": 2, 1055 | "strokeStyle": "solid", 1056 | "roughness": 1, 1057 | "opacity": 100, 1058 | "groupIds": [], 1059 | "frameId": null, 1060 | "index": "aP", 1061 | "roundness": null, 1062 | "seed": 965257717, 1063 | "version": 726, 1064 | "versionNonce": 1571362357, 1065 | "isDeleted": false, 1066 | "boundElements": null, 1067 | "updated": 1741161164500, 1068 | "link": null, 1069 | "locked": false, 1070 | "text": "Here is some more data that you requested\n(could be from Internet or any other source\nlike a PDF file)", 1071 | "fontSize": 20, 1072 | "fontFamily": 5, 1073 | "textAlign": "left", 1074 | "verticalAlign": "top", 1075 | "containerId": null, 1076 | "originalText": "Here is some more data that you requested (could be from Internet or any other source like a PDF file)", 1077 | "autoResize": false, 1078 | "lineHeight": 1.25 1079 | }, 1080 | { 1081 | "id": "vb7ledYlHl4C_XRcM9Z6t", 1082 | "type": "arrow", 1083 | "x": 938.7578125, 1084 | "y": 624.7110595703125, 1085 | "width": 378.921875, 1086 | "height": 57.41796875, 1087 | "angle": 0, 1088 | "strokeColor": "#1e1e1e", 1089 | "backgroundColor": "#96f2d7", 1090 | "fillStyle": "solid", 1091 | "strokeWidth": 2, 1092 | "strokeStyle": "solid", 1093 | "roughness": 1, 1094 | "opacity": 100, 1095 | "groupIds": [], 1096 | "frameId": null, 1097 | "index": "aQ", 1098 | "roundness": { 1099 | "type": 2 1100 | }, 1101 | "seed": 996061851, 1102 | "version": 689, 1103 | "versionNonce": 426739797, 1104 | "isDeleted": false, 1105 | "boundElements": [ 1106 | { 1107 | "type": "text", 1108 | "id": "cmbcfaOqmFcLahM-yCtCa" 1109 | } 1110 | ], 1111 | "updated": 1741161414608, 1112 | "link": null, 1113 | "locked": false, 1114 | "points": [ 1115 | [ 1116 | 0, 1117 | 0 1118 | ], 1119 | [ 1120 | 178.88671875, 1121 | 27.3984375 1122 | ], 1123 | [ 1124 | 378.921875, 1125 | 57.41796875 1126 | ] 1127 | ], 1128 | "lastCommittedPoint": null, 1129 | "startBinding": { 1130 | "elementId": "RjDEa2H5OJsqbNirZbQOK", 1131 | "focus": 0.34817129541226516, 1132 | "gap": 5.288207818854554 1133 | }, 1134 | "endBinding": { 1135 | "elementId": "-k91PM7OeuHp2iY1FTEzJ", 1136 | "focus": -0.488905734281415, 1137 | "gap": 7.8359375 1138 | }, 1139 | "startArrowhead": null, 1140 | "endArrowhead": "arrow", 1141 | "elbowed": false 1142 | }, 1143 | { 1144 | "id": "cmbcfaOqmFcLahM-yCtCa", 1145 | "type": "text", 1146 | "x": 1111.750503540039, 1147 | "y": 617.3321533203125, 1148 | "width": 15.623992919921875, 1149 | "height": 35, 1150 | "angle": 0, 1151 | "strokeColor": "#1e1e1e", 1152 | "backgroundColor": "#96f2d7", 1153 | "fillStyle": "solid", 1154 | "strokeWidth": 2, 1155 | "strokeStyle": "solid", 1156 | "roughness": 1, 1157 | "opacity": 100, 1158 | "groupIds": [], 1159 | "frameId": null, 1160 | "index": "aR", 1161 | "roundness": null, 1162 | "seed": 556464251, 1163 | "version": 7, 1164 | "versionNonce": 493589371, 1165 | "isDeleted": false, 1166 | "boundElements": null, 1167 | "updated": 1741161414608, 1168 | "link": null, 1169 | "locked": false, 1170 | "text": "7", 1171 | "fontSize": 28, 1172 | "fontFamily": 5, 1173 | "textAlign": "center", 1174 | "verticalAlign": "middle", 1175 | "containerId": "vb7ledYlHl4C_XRcM9Z6t", 1176 | "originalText": "7", 1177 | "autoResize": true, 1178 | "lineHeight": 1.25 1179 | }, 1180 | { 1181 | "id": "YBrrCS4RPtGXsCY-qFzLi", 1182 | "type": "arrow", 1183 | "x": 1321.68359375, 1184 | "y": 731.6190185546875, 1185 | "width": 418.2109375, 1186 | "height": 71.44140625, 1187 | "angle": 0, 1188 | "strokeColor": "#d2bab0", 1189 | "backgroundColor": "#96f2d7", 1190 | "fillStyle": "solid", 1191 | "strokeWidth": 2, 1192 | "strokeStyle": "solid", 1193 | "roughness": 1, 1194 | "opacity": 100, 1195 | "groupIds": [], 1196 | "frameId": null, 1197 | "index": "aT", 1198 | "roundness": { 1199 | "type": 2 1200 | }, 1201 | "seed": 804643003, 1202 | "version": 173, 1203 | "versionNonce": 2102667387, 1204 | "isDeleted": false, 1205 | "boundElements": [ 1206 | { 1207 | "type": "text", 1208 | "id": "OR2I9ov1klUN8LHYaHjW9" 1209 | } 1210 | ], 1211 | "updated": 1741161427336, 1212 | "link": null, 1213 | "locked": false, 1214 | "points": [ 1215 | [ 1216 | 0, 1217 | 0 1218 | ], 1219 | [ 1220 | -418.2109375, 1221 | -71.44140625 1222 | ] 1223 | ], 1224 | "lastCommittedPoint": null, 1225 | "startBinding": { 1226 | "elementId": "-k91PM7OeuHp2iY1FTEzJ", 1227 | "focus": -0.7007856750283342, 1228 | "gap": 3.83203125 1229 | }, 1230 | "endBinding": { 1231 | "elementId": "RjDEa2H5OJsqbNirZbQOK", 1232 | "focus": 0.6200223162058145, 1233 | "gap": 3.172671067134132 1234 | }, 1235 | "startArrowhead": null, 1236 | "endArrowhead": "arrow", 1237 | "elbowed": false 1238 | }, 1239 | { 1240 | "id": "OR2I9ov1klUN8LHYaHjW9", 1241 | "type": "text", 1242 | "x": 1103.6741256713867, 1243 | "y": 678.3983154296875, 1244 | "width": 17.807998657226562, 1245 | "height": 35, 1246 | "angle": 0, 1247 | "strokeColor": "#d2bab0", 1248 | "backgroundColor": "#96f2d7", 1249 | "fillStyle": "solid", 1250 | "strokeWidth": 2, 1251 | "strokeStyle": "solid", 1252 | "roughness": 1, 1253 | "opacity": 100, 1254 | "groupIds": [], 1255 | "frameId": null, 1256 | "index": "aU", 1257 | "roundness": null, 1258 | "seed": 456627829, 1259 | "version": 12, 1260 | "versionNonce": 1337782453, 1261 | "isDeleted": false, 1262 | "boundElements": null, 1263 | "updated": 1741161427336, 1264 | "link": null, 1265 | "locked": false, 1266 | "text": "8", 1267 | "fontSize": 28, 1268 | "fontFamily": 5, 1269 | "textAlign": "center", 1270 | "verticalAlign": "middle", 1271 | "containerId": "YBrrCS4RPtGXsCY-qFzLi", 1272 | "originalText": "8", 1273 | "autoResize": true, 1274 | "lineHeight": 1.25 1275 | } 1276 | ], 1277 | "appState": { 1278 | "gridSize": 20, 1279 | "gridStep": 5, 1280 | "gridModeEnabled": false, 1281 | "viewBackgroundColor": "#ffffff" 1282 | }, 1283 | "files": {} 1284 | } -------------------------------------------------------------------------------- /finance-agent.py: -------------------------------------------------------------------------------- 1 | from agno.agent import Agent 2 | from agno.models.ollama import Ollama 3 | from agno.tools.yfinance import YFinanceTools 4 | 5 | 6 | def get_stock_ticker_symbol(company_name: str) -> str: 7 | """Retrieve the stock ticker symbol for a given company listed on the Stock exchange. 8 | 9 | Args: 10 | company_name (str): The full name of the company. 11 | 12 | Returns: 13 | str: The stock ticker symbol of the company if found; otherwise, 'Unknown'. 14 | """ 15 | symbols = { 16 | "Apple": "AAPL", 17 | "Microsoft": "MSFT", 18 | "Amazon": "AMZN", 19 | "Meta": "META", 20 | "Google": "GOOGL", 21 | "Nvidia": "NVDA", 22 | "Advanced Micro Devices": "AMD", 23 | } 24 | return symbols.get(company_name, "Unknown") 25 | 26 | 27 | agent = Agent( 28 | model=Ollama(id="qwen2.5:1.5b"), # deepseek-r1:8b is not supported 29 | tools=[ 30 | YFinanceTools( 31 | stock_price=True, 32 | analyst_recommendations=True, 33 | stock_fundamentals=True, 34 | historical_prices=True, 35 | company_info=True, 36 | company_news=True, 37 | ), 38 | get_stock_ticker_symbol, 39 | ], 40 | instructions=[ 41 | "Use concise tables to display data.", 42 | "If you need to find the symbol for a company, use the get_stock_ticker_symbol tool.", 43 | ], 44 | add_datetime_to_instructions=True, 45 | show_tool_calls=True, 46 | markdown=True, 47 | # debug_mode=True, 48 | ) 49 | 50 | agent.print_response( 51 | "Summarize and compare analyst recommendations and fundamentals for Microsoft and Google. Which one is the favorite among traders ? Keep the entire answer in under 200 words.", 52 | stream=True, 53 | ) 54 | -------------------------------------------------------------------------------- /image-agent.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | 3 | from agno.agent import Agent 4 | from agno.media import Image 5 | from agno.models.ollama import Ollama 6 | 7 | agent = Agent( 8 | model=Ollama(id="llama3.2-vision"), 9 | markdown=True, 10 | ) 11 | 12 | image_path = Path(__file__).parent.joinpath("./images/ai-agents-architecture.png") 13 | 14 | agent.print_response( 15 | "Describe the concept explained in the image.", 16 | images=[Image(filepath=image_path)], 17 | ) 18 | -------------------------------------------------------------------------------- /images/agent-teams.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebDevCaptain/agno-ai-agents/60cb36a311e349c70b418916fbb2e4c81d9f1c65/images/agent-teams.png -------------------------------------------------------------------------------- /images/ai-agents-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebDevCaptain/agno-ai-agents/60cb36a311e349c70b418916fbb2e4c81d9f1c65/images/ai-agents-architecture.png -------------------------------------------------------------------------------- /images/ai-agents-architecture.svg: -------------------------------------------------------------------------------- 1 | User PromptData Sources(could beembeddings froma vector DB)AgentFrameworkTools(APIs)LLM (Llama, Deepseek,OpenAI models)1234I want to use a tool56Here is some more data that you requested(could be from Internet or any other sourcelike a PDF file)78 -------------------------------------------------------------------------------- /images/finance-agent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebDevCaptain/agno-ai-agents/60cb36a311e349c70b418916fbb2e4c81d9f1c65/images/finance-agent.png -------------------------------------------------------------------------------- /images/image-agent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebDevCaptain/agno-ai-agents/60cb36a311e349c70b418916fbb2e4c81d9f1c65/images/image-agent.png -------------------------------------------------------------------------------- /images/ollama-agent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebDevCaptain/agno-ai-agents/60cb36a311e349c70b418916fbb2e4c81d9f1c65/images/ollama-agent.png -------------------------------------------------------------------------------- /knowledge-agent.py: -------------------------------------------------------------------------------- 1 | from agno.agent import Agent 2 | from agno.embedder.ollama import OllamaEmbedder 3 | from agno.knowledge.pdf import PDFKnowledgeBase 4 | from agno.models.ollama import Ollama 5 | from agno.vectordb.chroma.chromadb import ChromaDb 6 | 7 | 8 | chroma_db = ChromaDb( 9 | collection="llm-tips", 10 | path="chroma.sqlite", 11 | persistent_client=True, 12 | embedder=OllamaEmbedder(id="llama3.2", dimensions=3072), 13 | ) 14 | 15 | 16 | knowledge_base = PDFKnowledgeBase(path="pdfs/How_I_Use_LLMs.pdf", vector_db=chroma_db) 17 | 18 | knowledge_base.load(recreate=False) # Comment out after first run 19 | 20 | agent = Agent( 21 | model=Ollama(id="llama3.2"), 22 | knowledge=knowledge_base, 23 | show_tool_calls=True, 24 | ) 25 | agent.print_response( 26 | "Give me a practical tip from Fundamentals of LLM Operations section.", 27 | markdown=False, 28 | ) 29 | -------------------------------------------------------------------------------- /ollama-agent.py: -------------------------------------------------------------------------------- 1 | from agno.agent import Agent 2 | from agno.models.ollama import Ollama 3 | 4 | agent = Agent(model=Ollama(id="deepseek-r1:8b")) # can also use qwen2.5:1.5b model 5 | 6 | agent.print_response( 7 | "Write a paragraph in 100 words about the future of finance", stream=True 8 | ) 9 | -------------------------------------------------------------------------------- /pdfs/How_I_Use_LLMs.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WebDevCaptain/agno-ai-agents/60cb36a311e349c70b418916fbb2e4c81d9f1c65/pdfs/How_I_Use_LLMs.pdf -------------------------------------------------------------------------------- /ping-ollama.sh: -------------------------------------------------------------------------------- 1 | # Ollama REST API 2 | 3 | # curl http://localhost:11434/api/generate -d '{ 4 | # "model": "deepseek-r1:8b", 5 | # "prompt":"Write a 10 line paragraph about the future of finance" 6 | # }' 7 | 8 | 9 | # curl http://localhost:11434/api/chat -d '{ 10 | # "model": "deepseek-r1:8b", 11 | # "messages": [ 12 | # { "role": "user", "content": "Write a 10 line paragraph about the future of finance" } 13 | # ] 14 | # }' -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "agno-demo" 3 | version = "0.1.0" 4 | description = "Finance agent using Agno and Ollama (Deepseek R1 - 8B and Qwen2.5 - 1.5B)." 5 | readme = "README.md" 6 | requires-python = ">=3.13.2" 7 | dependencies = [ 8 | "agno>=1.1.7", 9 | "black>=25.1.0", 10 | "chromadb>=0.6.3", 11 | "duckduckgo-search>=7.5.0", 12 | "ollama>=0.4.7", 13 | "openai>=1.65.2", 14 | "pypdf>=5.3.1", 15 | "yfinance>=0.2.54", 16 | ] 17 | --------------------------------------------------------------------------------