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.
- rai_core-2.0.0a0/PKG-INFO +129 -0
- rai_core-2.0.0a0/README.md +89 -0
- rai_core-2.0.0a0/pyproject.toml +46 -0
- rai_core-2.0.0a0/rai/__init__.py +32 -0
- rai_core-2.0.0a0/rai/agents/__init__.py +28 -0
- rai_core-2.0.0a0/rai/agents/base.py +34 -0
- rai_core-2.0.0a0/rai/agents/conversational_agent.py +81 -0
- rai_core-2.0.0a0/rai/agents/integrations/__init__.py +13 -0
- rai_core-2.0.0a0/rai/agents/integrations/streamlit.py +183 -0
- rai_core-2.0.0a0/rai/agents/langchain/__init__.py +36 -0
- rai_core-2.0.0a0/rai/agents/langchain/agent.py +259 -0
- rai_core-2.0.0a0/rai/agents/langchain/callback.py +99 -0
- rai_core-2.0.0a0/rai/agents/langchain/react_agent.py +42 -0
- rai_core-2.0.0a0/rai/agents/langchain/runnables.py +178 -0
- rai_core-2.0.0a0/rai/agents/langchain/state_based_agent.py +187 -0
- rai_core-2.0.0a0/rai/agents/ros2/__init__.py +16 -0
- rai_core-2.0.0a0/rai/agents/ros2/state_based_agent.py +21 -0
- rai_core-2.0.0a0/rai/agents/runner.py +112 -0
- rai_core-2.0.0a0/rai/agents/tool_runner.py +146 -0
- rai_core-2.0.0a0/rai/aggregators/__init__.py +17 -0
- rai_core-2.0.0a0/rai/aggregators/base.py +53 -0
- rai_core-2.0.0a0/rai/aggregators/ros2/__init__.py +27 -0
- rai_core-2.0.0a0/rai/aggregators/ros2/aggregators.py +169 -0
- rai_core-2.0.0a0/rai/apps/__init__.py +13 -0
- rai_core-2.0.0a0/rai/apps/document_loader.py +76 -0
- rai_core-2.0.0a0/rai/apps/high_level_api.py +48 -0
- rai_core-2.0.0a0/rai/apps/state_analyzer.py +50 -0
- rai_core-2.0.0a0/rai/apps/talk_to_docs.py +103 -0
- rai_core-2.0.0a0/rai/apps/task_executor.py +159 -0
- rai_core-2.0.0a0/rai/apps/task_planner.py +71 -0
- rai_core-2.0.0a0/rai/cli/__init__.py +13 -0
- rai_core-2.0.0a0/rai/cli/rai_cli.py +242 -0
- rai_core-2.0.0a0/rai/cli/resources/default_robot_constitution.txt +11 -0
- rai_core-2.0.0a0/rai/communication/__init__.py +23 -0
- rai_core-2.0.0a0/rai/communication/base_connector.py +258 -0
- rai_core-2.0.0a0/rai/communication/hri_connector.py +175 -0
- rai_core-2.0.0a0/rai/communication/ros2/__init__.py +38 -0
- rai_core-2.0.0a0/rai/communication/ros2/api/__init__.py +39 -0
- rai_core-2.0.0a0/rai/communication/ros2/api/action.py +288 -0
- rai_core-2.0.0a0/rai/communication/ros2/api/base.py +144 -0
- rai_core-2.0.0a0/rai/communication/ros2/api/conversion.py +120 -0
- rai_core-2.0.0a0/rai/communication/ros2/api/service.py +90 -0
- rai_core-2.0.0a0/rai/communication/ros2/api/topic.py +460 -0
- rai_core-2.0.0a0/rai/communication/ros2/connectors/__init__.py +27 -0
- rai_core-2.0.0a0/rai/communication/ros2/connectors/action_mixin.py +59 -0
- rai_core-2.0.0a0/rai/communication/ros2/connectors/base.py +293 -0
- rai_core-2.0.0a0/rai/communication/ros2/connectors/hri_connector.py +80 -0
- rai_core-2.0.0a0/rai/communication/ros2/connectors/ros2_connector.py +20 -0
- rai_core-2.0.0a0/rai/communication/ros2/connectors/service_mixin.py +50 -0
- rai_core-2.0.0a0/rai/communication/ros2/context.py +221 -0
- rai_core-2.0.0a0/rai/communication/ros2/messages.py +108 -0
- rai_core-2.0.0a0/rai/communication/ros2/ros_async.py +37 -0
- rai_core-2.0.0a0/rai/communication/ros2/ros_logs.py +170 -0
- rai_core-2.0.0a0/rai/communication/sound_device/__init__.py +31 -0
- rai_core-2.0.0a0/rai/communication/sound_device/api.py +343 -0
- rai_core-2.0.0a0/rai/communication/sound_device/connector.py +290 -0
- rai_core-2.0.0a0/rai/config/__init__.py +13 -0
- rai_core-2.0.0a0/rai/config/models.py +60 -0
- rai_core-2.0.0a0/rai/extensions/__init__.py +13 -0
- rai_core-2.0.0a0/rai/frontend/__init__.py +17 -0
- rai_core-2.0.0a0/rai/frontend/configurator.py +1006 -0
- rai_core-2.0.0a0/rai/frontend/streamlit.py +57 -0
- rai_core-2.0.0a0/rai/initialization/__init__.py +29 -0
- rai_core-2.0.0a0/rai/initialization/model_initialization.py +307 -0
- rai_core-2.0.0a0/rai/messages/__init__.py +47 -0
- rai_core-2.0.0a0/rai/messages/artifacts.py +57 -0
- rai_core-2.0.0a0/rai/messages/conversion.py +53 -0
- rai_core-2.0.0a0/rai/messages/multimodal.py +155 -0
- rai_core-2.0.0a0/rai/tools/__init__.py +13 -0
- rai_core-2.0.0a0/rai/tools/ros2/__init__.py +104 -0
- rai_core-2.0.0a0/rai/tools/ros2/base.py +102 -0
- rai_core-2.0.0a0/rai/tools/ros2/cli.py +183 -0
- rai_core-2.0.0a0/rai/tools/ros2/generic/__init__.py +59 -0
- rai_core-2.0.0a0/rai/tools/ros2/generic/actions.py +270 -0
- rai_core-2.0.0a0/rai/tools/ros2/generic/interface_parser.py +164 -0
- rai_core-2.0.0a0/rai/tools/ros2/generic/services.py +109 -0
- rai_core-2.0.0a0/rai/tools/ros2/generic/toolkit.py +50 -0
- rai_core-2.0.0a0/rai/tools/ros2/generic/topics.py +252 -0
- rai_core-2.0.0a0/rai/tools/ros2/manipulation/__init__.py +28 -0
- rai_core-2.0.0a0/rai/tools/ros2/manipulation/custom.py +184 -0
- rai_core-2.0.0a0/rai/tools/ros2/navigation/__init__.py +31 -0
- rai_core-2.0.0a0/rai/tools/ros2/navigation/nav2.py +304 -0
- rai_core-2.0.0a0/rai/tools/ros2/simple.py +67 -0
- rai_core-2.0.0a0/rai/tools/time.py +47 -0
- rai_core-2.0.0a0/rai/types/__init__.py +46 -0
- rai_core-2.0.0a0/rai/types/base.py +34 -0
- rai_core-2.0.0a0/rai/types/geometry.py +56 -0
- rai_core-2.0.0a0/rai/types/rai_interfaces.py +67 -0
- rai_core-2.0.0a0/rai/types/ros2/__init__.py +24 -0
- rai_core-2.0.0a0/rai/types/ros2/convert.py +48 -0
- rai_core-2.0.0a0/rai/types/sensor.py +45 -0
- rai_core-2.0.0a0/rai/types/std.py +31 -0
- 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
|
+

|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
56
|
+

|
|
57
|
+

|
|
58
|
+
|
|
59
|
+

|
|
60
|
+

|
|
61
|
+

|
|
62
|
+

|
|
63
|
+

|
|
64
|
+

|
|
65
|
+
|
|
66
|
+
[](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
|
+

|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
[](https://opensource.org/licenses/Apache-2.0)
|
|
17
|
+

|
|
18
|
+

|
|
19
|
+
|
|
20
|
+

|
|
21
|
+

|
|
22
|
+

|
|
23
|
+

|
|
24
|
+

|
|
25
|
+

|
|
26
|
+
|
|
27
|
+
[](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
|
+
)
|