rai_core 2.0.0a0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. rai_core-2.0.0a0/PKG-INFO +129 -0
  2. rai_core-2.0.0a0/README.md +89 -0
  3. rai_core-2.0.0a0/pyproject.toml +46 -0
  4. rai_core-2.0.0a0/rai/__init__.py +32 -0
  5. rai_core-2.0.0a0/rai/agents/__init__.py +28 -0
  6. rai_core-2.0.0a0/rai/agents/base.py +34 -0
  7. rai_core-2.0.0a0/rai/agents/conversational_agent.py +81 -0
  8. rai_core-2.0.0a0/rai/agents/integrations/__init__.py +13 -0
  9. rai_core-2.0.0a0/rai/agents/integrations/streamlit.py +183 -0
  10. rai_core-2.0.0a0/rai/agents/langchain/__init__.py +36 -0
  11. rai_core-2.0.0a0/rai/agents/langchain/agent.py +259 -0
  12. rai_core-2.0.0a0/rai/agents/langchain/callback.py +99 -0
  13. rai_core-2.0.0a0/rai/agents/langchain/react_agent.py +42 -0
  14. rai_core-2.0.0a0/rai/agents/langchain/runnables.py +178 -0
  15. rai_core-2.0.0a0/rai/agents/langchain/state_based_agent.py +187 -0
  16. rai_core-2.0.0a0/rai/agents/ros2/__init__.py +16 -0
  17. rai_core-2.0.0a0/rai/agents/ros2/state_based_agent.py +21 -0
  18. rai_core-2.0.0a0/rai/agents/runner.py +112 -0
  19. rai_core-2.0.0a0/rai/agents/tool_runner.py +146 -0
  20. rai_core-2.0.0a0/rai/aggregators/__init__.py +17 -0
  21. rai_core-2.0.0a0/rai/aggregators/base.py +53 -0
  22. rai_core-2.0.0a0/rai/aggregators/ros2/__init__.py +27 -0
  23. rai_core-2.0.0a0/rai/aggregators/ros2/aggregators.py +169 -0
  24. rai_core-2.0.0a0/rai/apps/__init__.py +13 -0
  25. rai_core-2.0.0a0/rai/apps/document_loader.py +76 -0
  26. rai_core-2.0.0a0/rai/apps/high_level_api.py +48 -0
  27. rai_core-2.0.0a0/rai/apps/state_analyzer.py +50 -0
  28. rai_core-2.0.0a0/rai/apps/talk_to_docs.py +103 -0
  29. rai_core-2.0.0a0/rai/apps/task_executor.py +159 -0
  30. rai_core-2.0.0a0/rai/apps/task_planner.py +71 -0
  31. rai_core-2.0.0a0/rai/cli/__init__.py +13 -0
  32. rai_core-2.0.0a0/rai/cli/rai_cli.py +242 -0
  33. rai_core-2.0.0a0/rai/cli/resources/default_robot_constitution.txt +11 -0
  34. rai_core-2.0.0a0/rai/communication/__init__.py +23 -0
  35. rai_core-2.0.0a0/rai/communication/base_connector.py +258 -0
  36. rai_core-2.0.0a0/rai/communication/hri_connector.py +175 -0
  37. rai_core-2.0.0a0/rai/communication/ros2/__init__.py +38 -0
  38. rai_core-2.0.0a0/rai/communication/ros2/api/__init__.py +39 -0
  39. rai_core-2.0.0a0/rai/communication/ros2/api/action.py +288 -0
  40. rai_core-2.0.0a0/rai/communication/ros2/api/base.py +144 -0
  41. rai_core-2.0.0a0/rai/communication/ros2/api/conversion.py +120 -0
  42. rai_core-2.0.0a0/rai/communication/ros2/api/service.py +90 -0
  43. rai_core-2.0.0a0/rai/communication/ros2/api/topic.py +460 -0
  44. rai_core-2.0.0a0/rai/communication/ros2/connectors/__init__.py +27 -0
  45. rai_core-2.0.0a0/rai/communication/ros2/connectors/action_mixin.py +59 -0
  46. rai_core-2.0.0a0/rai/communication/ros2/connectors/base.py +293 -0
  47. rai_core-2.0.0a0/rai/communication/ros2/connectors/hri_connector.py +80 -0
  48. rai_core-2.0.0a0/rai/communication/ros2/connectors/ros2_connector.py +20 -0
  49. rai_core-2.0.0a0/rai/communication/ros2/connectors/service_mixin.py +50 -0
  50. rai_core-2.0.0a0/rai/communication/ros2/context.py +221 -0
  51. rai_core-2.0.0a0/rai/communication/ros2/messages.py +108 -0
  52. rai_core-2.0.0a0/rai/communication/ros2/ros_async.py +37 -0
  53. rai_core-2.0.0a0/rai/communication/ros2/ros_logs.py +170 -0
  54. rai_core-2.0.0a0/rai/communication/sound_device/__init__.py +31 -0
  55. rai_core-2.0.0a0/rai/communication/sound_device/api.py +343 -0
  56. rai_core-2.0.0a0/rai/communication/sound_device/connector.py +290 -0
  57. rai_core-2.0.0a0/rai/config/__init__.py +13 -0
  58. rai_core-2.0.0a0/rai/config/models.py +60 -0
  59. rai_core-2.0.0a0/rai/extensions/__init__.py +13 -0
  60. rai_core-2.0.0a0/rai/frontend/__init__.py +17 -0
  61. rai_core-2.0.0a0/rai/frontend/configurator.py +1006 -0
  62. rai_core-2.0.0a0/rai/frontend/streamlit.py +57 -0
  63. rai_core-2.0.0a0/rai/initialization/__init__.py +29 -0
  64. rai_core-2.0.0a0/rai/initialization/model_initialization.py +307 -0
  65. rai_core-2.0.0a0/rai/messages/__init__.py +47 -0
  66. rai_core-2.0.0a0/rai/messages/artifacts.py +57 -0
  67. rai_core-2.0.0a0/rai/messages/conversion.py +53 -0
  68. rai_core-2.0.0a0/rai/messages/multimodal.py +155 -0
  69. rai_core-2.0.0a0/rai/tools/__init__.py +13 -0
  70. rai_core-2.0.0a0/rai/tools/ros2/__init__.py +104 -0
  71. rai_core-2.0.0a0/rai/tools/ros2/base.py +102 -0
  72. rai_core-2.0.0a0/rai/tools/ros2/cli.py +183 -0
  73. rai_core-2.0.0a0/rai/tools/ros2/generic/__init__.py +59 -0
  74. rai_core-2.0.0a0/rai/tools/ros2/generic/actions.py +270 -0
  75. rai_core-2.0.0a0/rai/tools/ros2/generic/interface_parser.py +164 -0
  76. rai_core-2.0.0a0/rai/tools/ros2/generic/services.py +109 -0
  77. rai_core-2.0.0a0/rai/tools/ros2/generic/toolkit.py +50 -0
  78. rai_core-2.0.0a0/rai/tools/ros2/generic/topics.py +252 -0
  79. rai_core-2.0.0a0/rai/tools/ros2/manipulation/__init__.py +28 -0
  80. rai_core-2.0.0a0/rai/tools/ros2/manipulation/custom.py +184 -0
  81. rai_core-2.0.0a0/rai/tools/ros2/navigation/__init__.py +31 -0
  82. rai_core-2.0.0a0/rai/tools/ros2/navigation/nav2.py +304 -0
  83. rai_core-2.0.0a0/rai/tools/ros2/simple.py +67 -0
  84. rai_core-2.0.0a0/rai/tools/time.py +47 -0
  85. rai_core-2.0.0a0/rai/types/__init__.py +46 -0
  86. rai_core-2.0.0a0/rai/types/base.py +34 -0
  87. rai_core-2.0.0a0/rai/types/geometry.py +56 -0
  88. rai_core-2.0.0a0/rai/types/rai_interfaces.py +67 -0
  89. rai_core-2.0.0a0/rai/types/ros2/__init__.py +24 -0
  90. rai_core-2.0.0a0/rai/types/ros2/convert.py +48 -0
  91. rai_core-2.0.0a0/rai/types/sensor.py +45 -0
  92. rai_core-2.0.0a0/rai/types/std.py +31 -0
  93. rai_core-2.0.0a0/rai/types/vision.py +54 -0
@@ -0,0 +1,129 @@
1
+ Metadata-Version: 2.3
2
+ Name: rai_core
3
+ Version: 2.0.0a0
4
+ Summary: Core functionality for RAI framework
5
+ Author: Maciej Majek
6
+ Author-email: maciej.majek@robotec.ai
7
+ Requires-Python: >=3.10,<3.13
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: License :: OSI Approved :: Apache Software License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.10
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Requires-Dist: coloredlogs (>=15.0.1,<16.0.0)
15
+ Requires-Dist: deprecated (>=1.2.14,<2.0.0)
16
+ Requires-Dist: langchain
17
+ Requires-Dist: langchain-aws
18
+ Requires-Dist: langchain-community
19
+ Requires-Dist: langchain-core (>=0.3,<0.4)
20
+ Requires-Dist: langchain-ollama
21
+ Requires-Dist: langchain-openai
22
+ Requires-Dist: langfuse (>=2.60.2,<3.0.0)
23
+ Requires-Dist: langgraph
24
+ Requires-Dist: langgraph-prebuilt
25
+ Requires-Dist: lark (>=1.1.9,<2.0.0)
26
+ Requires-Dist: numpy (<2.0)
27
+ Requires-Dist: opencv-python (>=4.9.0.80,<5.0.0.0)
28
+ Requires-Dist: pillow (>=11.0.0,<12.0.0)
29
+ Requires-Dist: pydub (>=0.25.1,<0.26.0)
30
+ Requires-Dist: requests (>=2.32.2,<3.0.0)
31
+ Requires-Dist: scipy (>=1.14.0,<2.0.0)
32
+ Requires-Dist: sounddevice (>=0.4.7,<0.5.0)
33
+ Requires-Dist: streamlit (>=1.44,<2.0)
34
+ Requires-Dist: tomli (>=2.0.1,<3.0.0)
35
+ Requires-Dist: tomli-w (>=1.1.0,<2.0.0)
36
+ Requires-Dist: tqdm (>=4.66.4,<5.0.0)
37
+ Requires-Dist: transforms3d (>=0.4.1,<0.5.0)
38
+ Description-Content-Type: text/markdown
39
+
40
+ # RAI
41
+
42
+ RAI is a flexible AI agent framework to develop and deploy Embodied AI features for your robots.
43
+
44
+ 📚 Visit [robotecai.github.io/rai](https://robotecai.github.io/rai/) for the latest documentation, setup
45
+ guide and tutorials. 📚
46
+
47
+ ---
48
+
49
+ <div align="center">
50
+
51
+ ![rai-image](./docs/imgs/RAI_simple_diagram_medium.png)
52
+
53
+ ---
54
+
55
+ [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
56
+ ![GitHub Release](https://img.shields.io/github/v/release/RobotecAI/rai)
57
+ ![Contributors](https://img.shields.io/github/contributors/robotecai/rai)
58
+
59
+ ![Static Badge](https://img.shields.io/badge/Ubuntu-24.04-orange)
60
+ ![Static Badge](https://img.shields.io/badge/Ubuntu-22.04-orange)
61
+ ![Static Badge](https://img.shields.io/badge/Python-3.12-blue)
62
+ ![Static Badge](https://img.shields.io/badge/Python-3.10-blue)
63
+ ![Static Badge](https://img.shields.io/badge/ROS2-jazzy-blue)
64
+ ![Static Badge](https://img.shields.io/badge/ROS2-humble-blue)
65
+
66
+ [![](https://dcbadge.limes.pink/api/server/https://discord.gg/3PGHgTaJSB)](https://discord.gg/3PGHgTaJSB)
67
+
68
+ </div>
69
+
70
+ ---
71
+
72
+ ## 🎯 Overview
73
+
74
+ | Category | Description | Features |
75
+ | ------------------------------ | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
76
+ | 🤖 **Multi-Agent Systems** | Empowering robotics with advanced AI capabilities | • Seamlessly integrate Gen AI capabilities into your robots<br>• Enable sophisticated agent-based architectures |
77
+ | 🔄 **Robot Intelligence** | Enhancing robotic systems with smart features | • Add natural human-robot interaction capabilities<br>• Bring flexible problem-solving to your existing stack<br>• Provide ready-to-use AI features out of the box |
78
+ | 🌟 **Multi-Modal Interaction** | Supporting diverse interaction capabilities | • Handle diverse data types natively<br>• Enable rich sensory integration<br>• Process multiple input/output modalities simultaneously |
79
+
80
+ ## RAI framework
81
+
82
+ - [x] rai core: Core functionality for multi-agent system, human-robot interaction and
83
+ multi-modalities.
84
+ - [x] rai whoami: Tool to extract and synthesize robot embodiment information from a structured
85
+ directory of documentation, images, and URDFs.
86
+ - [x] rai_asr: Speech-to-text models and tools.
87
+ - [x] rai_tts: Text-to-speech models and tools.
88
+ - [x] rai_sim: Package for connecting RAI to simulation environments.
89
+ - [x] rai_bench: Benchmarking suite for RAI. Test agents, models, tools, simulators, etc.
90
+ - [x] rai_openset: Openset detection models and tools.
91
+ - [x] rai_nomad: Integration with NoMaD for navigation.
92
+ - [ ] rai_finetune: Finetune LLMs on your embodied data.
93
+
94
+ ### Simulation demos
95
+
96
+ Try RAI yourself with these demos:
97
+ | Application | Robot | Description | Docs Link |
98
+ | ------------------------------------------ | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------- |
99
+ | Mission and obstacle reasoning in orchards | Autonomous tractor | In a beautiful scene of a virtual orchard, RAI goes beyond obstacle detection to analyze best course of action for a given unexpected situation. | [link](https://robotecai.github.io/rai/demos/agriculture/) |
100
+ | Manipulation tasks with natural language | Robot Arm (Franka Panda) | Complete flexible manipulation tasks thanks to RAI and Grounded SAM 2 | [link](https://robotecai.github.io/rai/demos/manipulation/) |
101
+ | Autonomous mobile robot demo | Husarion ROSbot XL | Demonstrate RAI's interaction with an autonomous mobile robot platform for navigation and control | [link](https://robotecai.github.io/rai/demos/rosbot_xl/) |
102
+ | Speech-to-speech interaction with autonomous taxi | Simulated car | Demonstrate RAI's speech-to-speech interaction capabilities for specifying destinations to an autonomous taxi in awsim with autoware environment | [link](https://robotecai.github.io/rai/demos/taxi/) |
103
+
104
+ ## Community
105
+
106
+ ### Embodied AI Community Group
107
+
108
+ RAI is one of the main projects in focus of the
109
+ [Embodied AI Community Group](https://github.com/ros-wg-embodied-ai). If you would like to join the
110
+ next meeting, look for it in the
111
+ [ROS Community Calendar](https://calendar.google.com/calendar/u/0/embed?src=c_3fc5c4d6ece9d80d49f136c1dcd54d7f44e1acefdbe87228c92ff268e85e2ea0@group.calendar.google.com&ctz=Etc/UTC).
112
+
113
+ ### Publicity
114
+
115
+ - A talk about [RAI at ROSCon 2024](https://vimeo.com/1026029511).
116
+
117
+ ### RAI Q&A
118
+
119
+ Please take a look at [Q&A](https://github.com/RobotecAI/rai/discussions/categories/q-a).
120
+
121
+ ### Developer Resources
122
+
123
+ See our [documentation](https://robotecai.github.io/rai/) for a deeper dive into RAI, including
124
+ instructions on creating a configuration specifically for your robot.
125
+
126
+ ### Contributing
127
+
128
+ You are welcome to contribute to RAI! Please see our [Contribution Guide](https://github.com/RobotecAI/rai/blob/development/CONTRIBUTING.md).
129
+
@@ -0,0 +1,89 @@
1
+ # RAI
2
+
3
+ RAI is a flexible AI agent framework to develop and deploy Embodied AI features for your robots.
4
+
5
+ 📚 Visit [robotecai.github.io/rai](https://robotecai.github.io/rai/) for the latest documentation, setup
6
+ guide and tutorials. 📚
7
+
8
+ ---
9
+
10
+ <div align="center">
11
+
12
+ ![rai-image](./docs/imgs/RAI_simple_diagram_medium.png)
13
+
14
+ ---
15
+
16
+ [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
17
+ ![GitHub Release](https://img.shields.io/github/v/release/RobotecAI/rai)
18
+ ![Contributors](https://img.shields.io/github/contributors/robotecai/rai)
19
+
20
+ ![Static Badge](https://img.shields.io/badge/Ubuntu-24.04-orange)
21
+ ![Static Badge](https://img.shields.io/badge/Ubuntu-22.04-orange)
22
+ ![Static Badge](https://img.shields.io/badge/Python-3.12-blue)
23
+ ![Static Badge](https://img.shields.io/badge/Python-3.10-blue)
24
+ ![Static Badge](https://img.shields.io/badge/ROS2-jazzy-blue)
25
+ ![Static Badge](https://img.shields.io/badge/ROS2-humble-blue)
26
+
27
+ [![](https://dcbadge.limes.pink/api/server/https://discord.gg/3PGHgTaJSB)](https://discord.gg/3PGHgTaJSB)
28
+
29
+ </div>
30
+
31
+ ---
32
+
33
+ ## 🎯 Overview
34
+
35
+ | Category | Description | Features |
36
+ | ------------------------------ | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
37
+ | 🤖 **Multi-Agent Systems** | Empowering robotics with advanced AI capabilities | • Seamlessly integrate Gen AI capabilities into your robots<br>• Enable sophisticated agent-based architectures |
38
+ | 🔄 **Robot Intelligence** | Enhancing robotic systems with smart features | • Add natural human-robot interaction capabilities<br>• Bring flexible problem-solving to your existing stack<br>• Provide ready-to-use AI features out of the box |
39
+ | 🌟 **Multi-Modal Interaction** | Supporting diverse interaction capabilities | • Handle diverse data types natively<br>• Enable rich sensory integration<br>• Process multiple input/output modalities simultaneously |
40
+
41
+ ## RAI framework
42
+
43
+ - [x] rai core: Core functionality for multi-agent system, human-robot interaction and
44
+ multi-modalities.
45
+ - [x] rai whoami: Tool to extract and synthesize robot embodiment information from a structured
46
+ directory of documentation, images, and URDFs.
47
+ - [x] rai_asr: Speech-to-text models and tools.
48
+ - [x] rai_tts: Text-to-speech models and tools.
49
+ - [x] rai_sim: Package for connecting RAI to simulation environments.
50
+ - [x] rai_bench: Benchmarking suite for RAI. Test agents, models, tools, simulators, etc.
51
+ - [x] rai_openset: Openset detection models and tools.
52
+ - [x] rai_nomad: Integration with NoMaD for navigation.
53
+ - [ ] rai_finetune: Finetune LLMs on your embodied data.
54
+
55
+ ### Simulation demos
56
+
57
+ Try RAI yourself with these demos:
58
+ | Application | Robot | Description | Docs Link |
59
+ | ------------------------------------------ | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------- |
60
+ | Mission and obstacle reasoning in orchards | Autonomous tractor | In a beautiful scene of a virtual orchard, RAI goes beyond obstacle detection to analyze best course of action for a given unexpected situation. | [link](https://robotecai.github.io/rai/demos/agriculture/) |
61
+ | Manipulation tasks with natural language | Robot Arm (Franka Panda) | Complete flexible manipulation tasks thanks to RAI and Grounded SAM 2 | [link](https://robotecai.github.io/rai/demos/manipulation/) |
62
+ | Autonomous mobile robot demo | Husarion ROSbot XL | Demonstrate RAI's interaction with an autonomous mobile robot platform for navigation and control | [link](https://robotecai.github.io/rai/demos/rosbot_xl/) |
63
+ | Speech-to-speech interaction with autonomous taxi | Simulated car | Demonstrate RAI's speech-to-speech interaction capabilities for specifying destinations to an autonomous taxi in awsim with autoware environment | [link](https://robotecai.github.io/rai/demos/taxi/) |
64
+
65
+ ## Community
66
+
67
+ ### Embodied AI Community Group
68
+
69
+ RAI is one of the main projects in focus of the
70
+ [Embodied AI Community Group](https://github.com/ros-wg-embodied-ai). If you would like to join the
71
+ next meeting, look for it in the
72
+ [ROS Community Calendar](https://calendar.google.com/calendar/u/0/embed?src=c_3fc5c4d6ece9d80d49f136c1dcd54d7f44e1acefdbe87228c92ff268e85e2ea0@group.calendar.google.com&ctz=Etc/UTC).
73
+
74
+ ### Publicity
75
+
76
+ - A talk about [RAI at ROSCon 2024](https://vimeo.com/1026029511).
77
+
78
+ ### RAI Q&A
79
+
80
+ Please take a look at [Q&A](https://github.com/RobotecAI/rai/discussions/categories/q-a).
81
+
82
+ ### Developer Resources
83
+
84
+ See our [documentation](https://robotecai.github.io/rai/) for a deeper dive into RAI, including
85
+ instructions on creating a configuration specifically for your robot.
86
+
87
+ ### Contributing
88
+
89
+ You are welcome to contribute to RAI! Please see our [Contribution Guide](https://github.com/RobotecAI/rai/blob/development/CONTRIBUTING.md).
@@ -0,0 +1,46 @@
1
+ [build-system]
2
+ requires = ["poetry-core>=1.0.0"]
3
+ build-backend = "poetry.core.masonry.api"
4
+
5
+ [tool.poetry]
6
+ name = "rai_core"
7
+ version = "2.0.0.a0"
8
+ description = "Core functionality for RAI framework"
9
+ authors = ["Maciej Majek <maciej.majek@robotec.ai>", "Bartłomiej Boczek <bartlomiej.boczek@robotec.ai>", "Kajetan Rachwał <kajetan.rachwal@robotec.ai>"]
10
+ readme = "README.md"
11
+ classifiers = [
12
+ "Programming Language :: Python :: 3",
13
+ "Development Status :: 4 - Beta",
14
+ "License :: OSI Approved :: Apache Software License",
15
+ ]
16
+ packages = [
17
+ { include = "rai", from = "." },
18
+ ]
19
+
20
+ [tool.poetry.dependencies]
21
+ python = "^3.10, <3.13"
22
+ langchain-core = "^0.3"
23
+ langgraph = "*"
24
+ langgraph-prebuilt = "*"
25
+ langchain = "*"
26
+ langchain-aws = "*"
27
+ langchain-openai = "*"
28
+ langchain-ollama = "*"
29
+ langchain-community = "*"
30
+
31
+ requests = "^2.32.2"
32
+ coloredlogs = "^15.0.1"
33
+ tqdm = "^4.66.4"
34
+ deprecated = "^1.2.14"
35
+ tomli = "^2.0.1"
36
+ tomli-w = "^1.1.0"
37
+ opencv-python = "^4.9.0.80"
38
+ lark = "^1.1.9"
39
+ transforms3d = "^0.4.1"
40
+ pillow = "^11.0.0"
41
+ langfuse = "^2.60.2"
42
+ pydub = "^0.25.1"
43
+ scipy = "^1.14.0"
44
+ sounddevice = "^0.4.7"
45
+ streamlit = "^1.44"
46
+ numpy = "<2.0"
@@ -0,0 +1,32 @@
1
+ # Copyright (C) 2025 Robotec.AI
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from .agents import AgentRunner, ReActAgent
16
+ from .initialization import (
17
+ get_embeddings_model,
18
+ get_llm_model,
19
+ get_llm_model_config_and_vendor,
20
+ get_llm_model_direct,
21
+ get_tracing_callbacks,
22
+ )
23
+
24
+ __all__ = [
25
+ "AgentRunner",
26
+ "ReActAgent",
27
+ "get_embeddings_model",
28
+ "get_llm_model",
29
+ "get_llm_model_config_and_vendor",
30
+ "get_llm_model_direct",
31
+ "get_tracing_callbacks",
32
+ ]
@@ -0,0 +1,28 @@
1
+ # Copyright (C) 2024 Robotec.AI
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from rai.agents.base import BaseAgent
16
+ from rai.agents.conversational_agent import create_conversational_agent
17
+ from rai.agents.langchain.react_agent import ReActAgent
18
+ from rai.agents.runner import AgentRunner, wait_for_shutdown
19
+ from rai.agents.tool_runner import ToolRunner
20
+
21
+ __all__ = [
22
+ "AgentRunner",
23
+ "BaseAgent",
24
+ "ReActAgent",
25
+ "ToolRunner",
26
+ "create_conversational_agent",
27
+ "wait_for_shutdown",
28
+ ]
@@ -0,0 +1,34 @@
1
+ # Copyright (C) 2024 Robotec.AI
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import logging
16
+ from abc import ABC, abstractmethod
17
+
18
+
19
+ class BaseAgent(ABC):
20
+ def __init__(self):
21
+ """Initializes a new agent instance and sets up logging with the class name."""
22
+ self.logger = logging.getLogger(self.__class__.__name__)
23
+
24
+ @abstractmethod
25
+ def run(self):
26
+ """Starts the agent's main execution loop.
27
+ In some cases, concrete run implementation may not be needed.
28
+ In that case use pass as a placeholder."""
29
+ pass
30
+
31
+ @abstractmethod
32
+ def stop(self):
33
+ """Gracefully terminates the agent's execution and cleans up resources."""
34
+ pass
@@ -0,0 +1,81 @@
1
+ # Copyright (C) 2024 Robotec.AI
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ import logging
17
+ from functools import partial
18
+ from typing import List, Optional, TypedDict
19
+
20
+ from langchain.chat_models.base import BaseChatModel
21
+ from langchain_core.messages import BaseMessage, SystemMessage
22
+ from langchain_core.tools import BaseTool
23
+ from langgraph.graph import START, StateGraph
24
+ from langgraph.graph.state import CompiledStateGraph
25
+ from langgraph.prebuilt.tool_node import tools_condition
26
+
27
+ from rai.agents.tool_runner import ToolRunner
28
+
29
+
30
+ class State(TypedDict):
31
+ messages: List[BaseMessage]
32
+
33
+
34
+ def agent(llm: BaseChatModel, logger: logging.Logger, system_prompt: str, state: State):
35
+ logger.info("Running thinker")
36
+
37
+ # If there are no messages, do nothing
38
+ if len(state["messages"]) == 0:
39
+ return state
40
+
41
+ # Insert system message if not already present
42
+ if not isinstance(state["messages"][0], SystemMessage):
43
+ state["messages"].insert(0, SystemMessage(content=system_prompt))
44
+ ai_msg = llm.invoke(state["messages"])
45
+ state["messages"].append(ai_msg)
46
+ return state
47
+
48
+
49
+ def create_conversational_agent(
50
+ llm: BaseChatModel,
51
+ tools: List[BaseTool],
52
+ system_prompt: str,
53
+ logger: Optional[logging.Logger] = None,
54
+ debug=False,
55
+ ) -> CompiledStateGraph:
56
+ _logger = None
57
+ if logger:
58
+ _logger = logger
59
+ else:
60
+ _logger = logging.getLogger(__name__)
61
+
62
+ _logger.info("Creating state based agent")
63
+
64
+ llm_with_tools = llm.bind_tools(tools)
65
+ tool_node = ToolRunner(tools=tools, logger=_logger)
66
+
67
+ workflow = StateGraph(State)
68
+ workflow.add_node("tools", tool_node)
69
+ workflow.add_node("thinker", partial(agent, llm_with_tools, _logger, system_prompt))
70
+
71
+ workflow.add_edge(START, "thinker")
72
+ workflow.add_edge("tools", "thinker")
73
+
74
+ workflow.add_conditional_edges(
75
+ "thinker",
76
+ tools_condition,
77
+ )
78
+
79
+ app = workflow.compile(debug=debug)
80
+ _logger.info("State based agent created")
81
+ return app
@@ -0,0 +1,13 @@
1
+ # Copyright (C) 2024 Robotec.AI
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
@@ -0,0 +1,183 @@
1
+ # Copyright (C) 2024 Robotec.AI
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import base64
16
+ import inspect
17
+ from typing import Any, Callable, Dict, List, TypeVar
18
+
19
+ import cv2
20
+ import numpy as np
21
+ import streamlit as st
22
+ from langchain_core.callbacks.base import BaseCallbackHandler
23
+ from langchain_core.messages import BaseMessage
24
+ from langchain_core.runnables import Runnable, RunnableConfig
25
+ from streamlit.delta_generator import DeltaGenerator
26
+ from streamlit.runtime.scriptrunner import add_script_run_ctx, get_script_run_ctx
27
+
28
+ # code inspired by (mostly copied, some changes were applied and might be updated in the future)
29
+ # https://github.com/shiv248/Streamlit-x-LangGraph-Cookbooks/tree/b8e623bdc9821fc1cf581607454dae1afc054df2/tool_calling_via_callback
30
+
31
+
32
+ # Define a function to create a callback handler for Streamlit that updates the UI dynamically
33
+ def get_streamlit_cb(parent_container: DeltaGenerator) -> BaseCallbackHandler:
34
+ """
35
+ Creates a Streamlit callback handler that updates the provided Streamlit container with new tokens.
36
+ Args:
37
+ parent_container (DeltaGenerator): The Streamlit container where the text will be rendered.
38
+ Returns:
39
+ BaseCallbackHandler: An instance of a callback handler configured for Streamlit.
40
+ """
41
+
42
+ # Define a custom callback handler class for managing and displaying stream events in Streamlit
43
+ class StreamHandler(BaseCallbackHandler):
44
+ """
45
+ Custom callback handler for Streamlit that updates a Streamlit container with new tokens.
46
+ """
47
+
48
+ def __init__(
49
+ self, container: st.delta_generator.DeltaGenerator, initial_text: str = ""
50
+ ):
51
+ """
52
+ Initializes the StreamHandler with a Streamlit container and optional initial text.
53
+ Args:
54
+ container (st.delta_generator.DeltaGenerator): The Streamlit container where text will be rendered.
55
+ initial_text (str): Optional initial text to start with in the container.
56
+ """
57
+ self.container = container # The Streamlit container to update
58
+ self.thoughts_placeholder = (
59
+ self.container.container()
60
+ ) # container to hold tool_call renders
61
+ self.tool_output_placeholder = None # placeholder for the output of the tool call to be in the expander
62
+ self.token_placeholder = self.container.empty() # for token streaming
63
+ self.text = (
64
+ initial_text # The text content to display, starting with initial text
65
+ )
66
+
67
+ def on_llm_new_token(self, token: str, **kwargs) -> None:
68
+ """
69
+ Callback method triggered when a new token is received (e.g., from a language model).
70
+ Args:
71
+ token (str): The new token received.
72
+ **kwargs: Additional keyword arguments.
73
+ """
74
+ self.text += token # Append the new token to the existing text
75
+ self.token_placeholder.write(self.text)
76
+
77
+ def on_tool_start(
78
+ self, serialized: Dict[str, Any], input_str: str, **kwargs: Any
79
+ ) -> None:
80
+ """
81
+ Run when the tool starts running.
82
+ Args:
83
+ serialized (Dict[str, Any]): The serialized tool.
84
+ input_str (str): The input string.
85
+ kwargs (Any): Additional keyword arguments.
86
+ """
87
+ with self.thoughts_placeholder:
88
+ status_placeholder = st.empty() # Placeholder to show the tool's status
89
+ with status_placeholder.status("Calling Tool...", expanded=True) as s:
90
+ st.write("Called tool: ", serialized["name"])
91
+ st.write("tool description: ", serialized["description"])
92
+ st.write("tool input: ")
93
+ st.code(input_str) # Display the input data sent to the tool
94
+ st.write("tool output: ")
95
+ # Placeholder for tool output that will be updated later below
96
+ self.tool_output_placeholder = st.empty()
97
+ s.update(
98
+ label="Completed Calling Tool!", expanded=False
99
+ ) # Update the status once done
100
+
101
+ def on_tool_end(self, output: Any, **kwargs: Any) -> Any:
102
+ """
103
+ Run when the tool ends.
104
+ Args:
105
+ output (Any): The output from the tool.
106
+ kwargs (Any): Additional keyword arguments.
107
+ """
108
+ # We assume that `on_tool_end` comes after `on_tool_start`, meaning output_placeholder exists
109
+ if self.tool_output_placeholder:
110
+ with self.tool_output_placeholder.container():
111
+ st.code(output.content) # Display the tool's output
112
+
113
+ if output.artifact is not None:
114
+ if "images" in output.artifact: # Display available images
115
+ for image in output.artifact["images"]:
116
+ image_cv2 = cv2.imdecode(
117
+ np.frombuffer(base64.b64decode(image), np.uint8),
118
+ cv2.IMREAD_COLOR,
119
+ )
120
+ st.image(
121
+ image_cv2, channels="BGR", use_container_width=True
122
+ )
123
+
124
+ # Define a type variable for generic type hinting in the decorator, to maintain
125
+ # input function and wrapped function return type
126
+ fn_return_type = TypeVar("fn_return_type")
127
+
128
+ # Decorator function to add the Streamlit execution context to a function
129
+ def add_streamlit_context(
130
+ fn: Callable[..., fn_return_type],
131
+ ) -> Callable[..., fn_return_type]:
132
+ """
133
+ Decorator to ensure that the decorated function runs within the Streamlit execution context.
134
+ Args:
135
+ fn (Callable[..., fn_return_type]): The function to be decorated.
136
+ Returns:
137
+ Callable[..., fn_return_type]: The decorated function that includes the Streamlit context setup.
138
+ """
139
+ ctx = (
140
+ get_script_run_ctx()
141
+ ) # Retrieve the current Streamlit script execution context
142
+
143
+ def wrapper(*args, **kwargs) -> fn_return_type:
144
+ """
145
+ Wrapper function that adds the Streamlit context and then calls the original function.
146
+ Args:
147
+ *args: Positional arguments to pass to the original function.
148
+ **kwargs: Keyword arguments to pass to the original function.
149
+ Returns:
150
+ fn_return_type: The result from the original function.
151
+ """
152
+ add_script_run_ctx(
153
+ ctx=ctx
154
+ ) # Add the Streamlit context to the current execution
155
+ return fn(*args, **kwargs) # Call the original function with its arguments
156
+
157
+ return wrapper
158
+
159
+ # Create an instance of the custom StreamHandler with the provided Streamlit container
160
+ st_cb = StreamHandler(parent_container)
161
+
162
+ # Iterate over all methods of the StreamHandler instance
163
+ for method_name, method_func in inspect.getmembers(
164
+ st_cb, predicate=inspect.ismethod
165
+ ):
166
+ if method_name.startswith("on_"): # Identify callback methods
167
+ setattr(
168
+ st_cb, method_name, add_streamlit_context(method_func)
169
+ ) # Wrap and replace the method
170
+
171
+ # Return the fully configured StreamHandler instance with the context-aware callback methods
172
+ return st_cb
173
+
174
+
175
+ def streamlit_invoke(
176
+ graph: Runnable[Any, Any], messages: List[BaseMessage], callables: List[Callable]
177
+ ):
178
+ if not isinstance(callables, list):
179
+ raise TypeError("callables must be a list")
180
+ return graph.invoke(
181
+ {"messages": messages},
182
+ config=RunnableConfig({"callbacks": callables, "recursion_limit": 100}),
183
+ )