iridet-bot 0.1.1a1__py3-none-any.whl
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.
- iribot/.env.example +4 -0
- iribot/__init__.py +5 -0
- iribot/__main__.py +7 -0
- iribot/ag_ui_protocol.py +247 -0
- iribot/agent.py +155 -0
- iribot/cli.py +33 -0
- iribot/config.py +45 -0
- iribot/executor.py +73 -0
- iribot/main.py +300 -0
- iribot/models.py +79 -0
- iribot/prompt_generator.py +104 -0
- iribot/session_manager.py +194 -0
- iribot/templates/system_prompt.j2 +185 -0
- iribot/tools/__init__.py +27 -0
- iribot/tools/base.py +80 -0
- iribot/tools/execute_command.py +572 -0
- iribot/tools/list_directory.py +49 -0
- iribot/tools/read_file.py +43 -0
- iribot/tools/write_file.py +49 -0
- iridet_bot-0.1.1a1.dist-info/METADATA +369 -0
- iridet_bot-0.1.1a1.dist-info/RECORD +24 -0
- iridet_bot-0.1.1a1.dist-info/WHEEL +5 -0
- iridet_bot-0.1.1a1.dist-info/entry_points.txt +2 -0
- iridet_bot-0.1.1a1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Write file tool"""
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Any, Dict
|
|
4
|
+
from .base import BaseTool
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class WriteFileTool(BaseTool):
|
|
8
|
+
"""Write content to files"""
|
|
9
|
+
|
|
10
|
+
@property
|
|
11
|
+
def name(self) -> str:
|
|
12
|
+
return "write_file"
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def description(self) -> str:
|
|
16
|
+
return "Write content to a file"
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def parameters(self) -> Dict[str, Any]:
|
|
20
|
+
return {
|
|
21
|
+
"type": "object",
|
|
22
|
+
"properties": {
|
|
23
|
+
"file_path": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"description": "Path to the file to write"
|
|
26
|
+
},
|
|
27
|
+
"content": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"description": "Content to write to the file"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"required": ["file_path", "content"]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
def execute(self, file_path: str, content: str) -> Dict[str, Any]:
|
|
36
|
+
"""Write content to file"""
|
|
37
|
+
try:
|
|
38
|
+
Path(file_path).parent.mkdir(parents=True, exist_ok=True)
|
|
39
|
+
with open(file_path, 'w', encoding='utf-8') as f:
|
|
40
|
+
f.write(content)
|
|
41
|
+
return {
|
|
42
|
+
"success": True,
|
|
43
|
+
"message": f"File written successfully: {file_path}"
|
|
44
|
+
}
|
|
45
|
+
except Exception as e:
|
|
46
|
+
return {
|
|
47
|
+
"success": False,
|
|
48
|
+
"error": str(e)
|
|
49
|
+
}
|
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: iridet-bot
|
|
3
|
+
Version: 0.1.1a1
|
|
4
|
+
Summary: Full-stack AI agent with Python backend and Vue frontend
|
|
5
|
+
Requires-Python: >=3.9
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: fastapi>=0.104.0
|
|
8
|
+
Requires-Dist: uvicorn>=0.24.0
|
|
9
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
10
|
+
Requires-Dist: openai>=1.0.0
|
|
11
|
+
Requires-Dist: pillow>=10.0.0
|
|
12
|
+
Requires-Dist: pydantic>=2.0.0
|
|
13
|
+
Requires-Dist: pydantic-settings>=2.0.0
|
|
14
|
+
Requires-Dist: aiofiles>=23.0.0
|
|
15
|
+
Requires-Dist: jinja2>=3.0.0
|
|
16
|
+
|
|
17
|
+
# IriBot - Lightweight AI Agent Chat System
|
|
18
|
+
|
|
19
|
+
A full-featured AI agent application with tool calling capabilities and real-time conversation experience. Built with Python FastAPI backend + Vue 3 frontend full-stack architecture.
|
|
20
|
+
|
|
21
|
+
## 📦 PyPI 发布与 CLI
|
|
22
|
+
|
|
23
|
+
- 安装:pip install iribot
|
|
24
|
+
- 运行:iribot --host 127.0.0.1 --port 8000
|
|
25
|
+
- 构建:使用 Makefile(make build,会自动构建前端并打包到后端静态资源)
|
|
26
|
+
|
|
27
|
+
## ✨ Key Features
|
|
28
|
+
|
|
29
|
+
### 🤖 AI Agent Conversation
|
|
30
|
+
|
|
31
|
+
- Intelligent conversation powered by OpenAI API
|
|
32
|
+
- Streaming response support for real-time AI replies
|
|
33
|
+
- Image input support (vision capabilities)
|
|
34
|
+
- Customizable system prompts
|
|
35
|
+
|
|
36
|
+
### 🛠️ Tool Calling System
|
|
37
|
+
|
|
38
|
+
The agent can autonomously call the following tools to complete tasks:
|
|
39
|
+
|
|
40
|
+
- **File Operations**
|
|
41
|
+
- `read_file` - Read file contents
|
|
42
|
+
- `write_file` - Create or modify files
|
|
43
|
+
- `list_directory` - List directory contents
|
|
44
|
+
|
|
45
|
+
- **Command Execution**
|
|
46
|
+
- `shell_start` - Start an interactive shell session
|
|
47
|
+
- `shell_run` - Execute commands in shell
|
|
48
|
+
- `shell_read` - Read shell output
|
|
49
|
+
- `shell_write` - Write input to shell
|
|
50
|
+
- `shell_stop` - Stop shell session
|
|
51
|
+
|
|
52
|
+
### 💬 Session Management
|
|
53
|
+
|
|
54
|
+
- Multi-session support, create multiple independent conversations
|
|
55
|
+
- Persistent session history storage
|
|
56
|
+
- Session list management (create, switch, delete)
|
|
57
|
+
- Independent system prompts for each session
|
|
58
|
+
|
|
59
|
+
### 🎨 Modern UI
|
|
60
|
+
|
|
61
|
+
- Beautiful interface based on TDesign component library
|
|
62
|
+
- Real-time tool call status display
|
|
63
|
+
- Markdown message rendering support
|
|
64
|
+
- Responsive design for different screen sizes
|
|
65
|
+
|
|
66
|
+
## 🏗️ System Architecture
|
|
67
|
+
|
|
68
|
+
```mermaid
|
|
69
|
+
graph TB
|
|
70
|
+
subgraph Frontend["Frontend Layer"]
|
|
71
|
+
A[ChatSidebar<br/>Session List]
|
|
72
|
+
B[ChatContainer<br/>Chat View]
|
|
73
|
+
C[ToolCallMessage<br/>Tool Call View]
|
|
74
|
+
FE[Vue 3 + TDesign UI + Vite]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
subgraph Backend["Backend Layer"]
|
|
78
|
+
D[main.py<br/>FastAPI Server]
|
|
79
|
+
E[agent.py<br/>AI Agent]
|
|
80
|
+
F[executor.py<br/>Tool Executor]
|
|
81
|
+
G[session_manager.py<br/>Session State Management]
|
|
82
|
+
H[tools/<br/>Tool Suite]
|
|
83
|
+
BE[FastAPI + OpenAI SDK]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
subgraph External["External Services"]
|
|
87
|
+
I[OpenAI API / Compatible LLM Service<br/>GPT-4, GPT-3.5, or Custom Models]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
Frontend -->|HTTP/SSE<br/>Server-Sent Events| Backend
|
|
91
|
+
Backend -->|OpenAI API| External
|
|
92
|
+
|
|
93
|
+
D --> E
|
|
94
|
+
E --> F
|
|
95
|
+
E --> G
|
|
96
|
+
F --> H
|
|
97
|
+
|
|
98
|
+
style Frontend fill:#e1f5ff
|
|
99
|
+
style Backend fill:#fff4e1
|
|
100
|
+
style External fill:#f0f0f0
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Data Flow
|
|
104
|
+
|
|
105
|
+
```mermaid
|
|
106
|
+
sequenceDiagram
|
|
107
|
+
participant User
|
|
108
|
+
participant Frontend
|
|
109
|
+
participant SessionManager
|
|
110
|
+
participant Agent
|
|
111
|
+
participant ToolExecutor
|
|
112
|
+
participant Tools
|
|
113
|
+
participant OpenAI
|
|
114
|
+
|
|
115
|
+
User->>Frontend: Input Message
|
|
116
|
+
Frontend->>SessionManager: POST /api/chat/stream
|
|
117
|
+
SessionManager->>SessionManager: Save user message
|
|
118
|
+
SessionManager->>Agent: Forward message
|
|
119
|
+
Agent->>OpenAI: Call OpenAI API
|
|
120
|
+
|
|
121
|
+
alt Text Response
|
|
122
|
+
OpenAI-->>Agent: Stream text content
|
|
123
|
+
Agent-->>Frontend: SSE stream
|
|
124
|
+
Frontend-->>User: Display in real-time
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
alt Tool Call Request
|
|
128
|
+
OpenAI-->>Agent: Return tool call request
|
|
129
|
+
Agent->>ToolExecutor: Execute tool
|
|
130
|
+
ToolExecutor->>Tools: Call specific tool
|
|
131
|
+
|
|
132
|
+
alt File Operations
|
|
133
|
+
Tools->>Tools: Read/Write file system
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
alt Shell Commands
|
|
137
|
+
Tools->>Tools: Execute shell commands
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
Tools-->>ToolExecutor: Return result
|
|
141
|
+
ToolExecutor-->>Agent: Tool execution result
|
|
142
|
+
Agent->>OpenAI: Send tool result
|
|
143
|
+
OpenAI-->>Agent: Continue generating response
|
|
144
|
+
Agent-->>Frontend: SSE stream
|
|
145
|
+
Frontend-->>User: Display response
|
|
146
|
+
end
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## 🚀 Quick Start
|
|
150
|
+
|
|
151
|
+
### Requirements
|
|
152
|
+
|
|
153
|
+
- Python 3.8+
|
|
154
|
+
- Node.js 16+
|
|
155
|
+
- OpenAI API Key (or compatible LLM service)
|
|
156
|
+
|
|
157
|
+
### Installation
|
|
158
|
+
|
|
159
|
+
#### 1. Clone the Repository
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
git clone <repository-url>
|
|
163
|
+
cd mybot
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
#### 2. Backend Setup
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
cd iribot
|
|
170
|
+
|
|
171
|
+
# Create virtual environment (recommended)
|
|
172
|
+
python -m venv venv
|
|
173
|
+
source venv/bin/activate # Windows: venv\Scripts\activate
|
|
174
|
+
|
|
175
|
+
# Install dependencies
|
|
176
|
+
pip install -r requirements.txt
|
|
177
|
+
|
|
178
|
+
# Configure environment variables
|
|
179
|
+
cp .env.example .env
|
|
180
|
+
# Edit .env file and add your OpenAI API Key
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
`.env` configuration example:
|
|
184
|
+
|
|
185
|
+
```ini
|
|
186
|
+
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
187
|
+
OPENAI_MODEL=gpt-4-turbo-preview
|
|
188
|
+
# OPENAI_BASE_URL=https://api.openai.com/v1 # Optional, use custom API endpoint
|
|
189
|
+
DEBUG=false
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### 3. Frontend Setup
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
cd frontend
|
|
196
|
+
|
|
197
|
+
# Install dependencies
|
|
198
|
+
npm install
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### 4. Start Services
|
|
202
|
+
|
|
203
|
+
##### Using Automated Scripts (Recommended)
|
|
204
|
+
|
|
205
|
+
**Windows:**
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
# In project root directory
|
|
209
|
+
./setup.bat
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**Linux/macOS:**
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
# In project root directory
|
|
216
|
+
chmod +x setup.sh
|
|
217
|
+
./setup.sh
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
##### Manual Start
|
|
221
|
+
|
|
222
|
+
**Backend:**
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
cd iribot
|
|
226
|
+
uvicorn main:app --reload --port 8000
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Frontend:**
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
cd frontend
|
|
233
|
+
npm run dev
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## 🔧 Configuration
|
|
237
|
+
|
|
238
|
+
### Backend Configuration
|
|
239
|
+
|
|
240
|
+
Configure in `iribot/.env` file:
|
|
241
|
+
|
|
242
|
+
| Config Item | Description | Default |
|
|
243
|
+
| ----------------- | -------------------- | ---------------------- |
|
|
244
|
+
| `OPENAI_API_KEY` | OpenAI API key | Required |
|
|
245
|
+
| `OPENAI_MODEL` | Model to use | `gpt-4-vision-preview` |
|
|
246
|
+
| `OPENAI_BASE_URL` | Custom API endpoint | Empty (use official) |
|
|
247
|
+
| `DEBUG` | Debug mode | `false` |
|
|
248
|
+
| `BASH_PATH` | Bash executable path | `bash` |
|
|
249
|
+
|
|
250
|
+
### Frontend Configuration
|
|
251
|
+
|
|
252
|
+
Frontend connects to backend via Vite proxy. Configuration file: `frontend/vite.config.js`
|
|
253
|
+
|
|
254
|
+
```javascript
|
|
255
|
+
export default {
|
|
256
|
+
server: {
|
|
257
|
+
proxy: {
|
|
258
|
+
"/api": {
|
|
259
|
+
target: "http://localhost:8000",
|
|
260
|
+
changeOrigin: true,
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## 🔌 API Endpoints
|
|
268
|
+
|
|
269
|
+
### Session Management
|
|
270
|
+
|
|
271
|
+
- `POST /api/sessions` - Create new session
|
|
272
|
+
- `GET /api/sessions` - Get session list
|
|
273
|
+
- `GET /api/sessions/{session_id}` - Get session details
|
|
274
|
+
- `DELETE /api/sessions/{session_id}` - Delete session
|
|
275
|
+
|
|
276
|
+
### Chat Interface
|
|
277
|
+
|
|
278
|
+
- `POST /api/chat/stream` - Send message (SSE streaming response)
|
|
279
|
+
|
|
280
|
+
### Tool Status
|
|
281
|
+
|
|
282
|
+
- `GET /api/tools/status` - Get all tool statuses
|
|
283
|
+
|
|
284
|
+
## 🛠️ Extension Development
|
|
285
|
+
|
|
286
|
+
### Adding New Tools
|
|
287
|
+
|
|
288
|
+
1. Create a new tool file in the `iribot/tools/` directory
|
|
289
|
+
2. Inherit from `BaseTool` class:
|
|
290
|
+
|
|
291
|
+
```python
|
|
292
|
+
from tools.base import BaseTool
|
|
293
|
+
|
|
294
|
+
class MyCustomTool(BaseTool):
|
|
295
|
+
@property
|
|
296
|
+
def name(self) -> str:
|
|
297
|
+
return "my_custom_tool"
|
|
298
|
+
|
|
299
|
+
@property
|
|
300
|
+
def description(self) -> str:
|
|
301
|
+
return "Tool description"
|
|
302
|
+
|
|
303
|
+
@property
|
|
304
|
+
def parameters(self) -> dict:
|
|
305
|
+
return {
|
|
306
|
+
"type": "object",
|
|
307
|
+
"properties": {
|
|
308
|
+
"param1": {
|
|
309
|
+
"type": "string",
|
|
310
|
+
"description": "Parameter description"
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
"required": ["param1"]
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
def execute(self, **kwargs) -> dict:
|
|
317
|
+
# Implement tool logic
|
|
318
|
+
return {
|
|
319
|
+
"success": True,
|
|
320
|
+
"result": "Execution result"
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
3. Register the tool in `executor.py`:
|
|
325
|
+
|
|
326
|
+
```python
|
|
327
|
+
def _register_default_tools(self):
|
|
328
|
+
# ... other tools
|
|
329
|
+
self.register_tool(MyCustomTool())
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Adding New Frontend Components
|
|
333
|
+
|
|
334
|
+
Add tool call visualization components in the `frontend/src/components/tool-calls/` directory.
|
|
335
|
+
|
|
336
|
+
## 📝 Tech Stack
|
|
337
|
+
|
|
338
|
+
### Backend
|
|
339
|
+
|
|
340
|
+
- **FastAPI** - Modern, fast web framework
|
|
341
|
+
- **OpenAI SDK** - LLM interface calling
|
|
342
|
+
- **Pydantic** - Data validation and settings management
|
|
343
|
+
- **Uvicorn** - ASGI server
|
|
344
|
+
|
|
345
|
+
### Frontend
|
|
346
|
+
|
|
347
|
+
- **Vue 3** - Progressive JavaScript framework
|
|
348
|
+
- **TDesign** - Enterprise-level UI component library
|
|
349
|
+
- **Vite** - Next-generation frontend build tool
|
|
350
|
+
- **Marked** - Markdown parser
|
|
351
|
+
|
|
352
|
+
## 🤝 Contributing
|
|
353
|
+
|
|
354
|
+
Issues and Pull Requests are welcome!
|
|
355
|
+
|
|
356
|
+
## 📄 License
|
|
357
|
+
|
|
358
|
+
MIT License
|
|
359
|
+
|
|
360
|
+
## 🔗 Related Links
|
|
361
|
+
|
|
362
|
+
- [OpenAI API Documentation](https://platform.openai.com/docs)
|
|
363
|
+
- [FastAPI Documentation](https://fastapi.tiangolo.com/)
|
|
364
|
+
- [Vue 3 Documentation](https://vuejs.org/)
|
|
365
|
+
- [TDesign Documentation](https://tdesign.tencent.com/vue-next/overview)
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
**Note:** Using this project requires a valid OpenAI API Key or compatible LLM service endpoint.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
iribot/.env.example,sha256=o8Njkm1VS5W_pv0fp-8act2VHrWm_6dQdMktOtm9fwM,96
|
|
2
|
+
iribot/__init__.py,sha256=rlvjWIl_KyNPoj-2peEjdKwYVB6xOwdYoMClKCMuhas,72
|
|
3
|
+
iribot/__main__.py,sha256=ls7HCIMJbxR8wU0izk-hR6LeXHfWJH6XfFUC-LNE6cE,102
|
|
4
|
+
iribot/ag_ui_protocol.py,sha256=_P7J-zEYN9eHpU0ky-tl8iigZ_fMPaU-uxC9BxbJUXM,8099
|
|
5
|
+
iribot/agent.py,sha256=no5lqHWG42balaIZaKRay2s3pxWMxH50CK8QzNJ1-C0,5203
|
|
6
|
+
iribot/cli.py,sha256=fT_xcB5kfmzAJBPdpB-cP0vGzDRp0x-lJwrxF1klT6U,885
|
|
7
|
+
iribot/config.py,sha256=8H_VmM6CTW_BxY6-46V_SAj_0c2mMhZ7lVu9sbQWnmo,1164
|
|
8
|
+
iribot/executor.py,sha256=7mx2U4lTPf2tD0VnxjnTHu53k-WNG8pQaA0x1695JEY,2395
|
|
9
|
+
iribot/main.py,sha256=qKSCgBEqXIxafFpEr5-7bPEYKLOIPta1TZ14XnYJiKM,11146
|
|
10
|
+
iribot/models.py,sha256=4j2_vQ6ZZ9l-lhlFvVuwjuwz-cX0beLuX-9wFV9ZP2o,2360
|
|
11
|
+
iribot/prompt_generator.py,sha256=Y-ctldfO-k7pCH5hqglfJ7i2hEY0iz-AJDKR1FB1Vto,3266
|
|
12
|
+
iribot/session_manager.py,sha256=nWXIKTO7vv5D_7tKdU3YMEsdnZsHC3bVKg3MTHEd6Ig,7523
|
|
13
|
+
iribot/templates/system_prompt.j2,sha256=mcqkwI4CTwsFIm7zqqI5a_axw0VRKZJNNZ9aYhDw99A,9631
|
|
14
|
+
iribot/tools/__init__.py,sha256=e661yHzkCARwoeNO3NLl-SJLDfRAMChC37eECmi07x8,616
|
|
15
|
+
iribot/tools/base.py,sha256=T2dbAI3BPDYRHHJ3wMCMWwpuI-kNa4b9KA0xxifNoBk,1791
|
|
16
|
+
iribot/tools/execute_command.py,sha256=YhfFgCdhZAMkPthXoYW21iKlAH-0YABYzIBd1b-E2Gc,18530
|
|
17
|
+
iribot/tools/list_directory.py,sha256=9MYO8hE7qG3qNap6fzLmmlJYfdjAKv1cYesNAYu3rYM,1299
|
|
18
|
+
iribot/tools/read_file.py,sha256=hcuiEZpio92U4YOAwX1LxbewJQR52A1jodpUehywxwE,1100
|
|
19
|
+
iribot/tools/write_file.py,sha256=6NAzz71iSvx-14fg4VqUU7l6t8_Dg8GFTjp_ZvwRlrU,1410
|
|
20
|
+
iridet_bot-0.1.1a1.dist-info/METADATA,sha256=Vv6L9UCtu_p9apvcFiu_elGLig3vCGp4YlkBuyh873g,8724
|
|
21
|
+
iridet_bot-0.1.1a1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
22
|
+
iridet_bot-0.1.1a1.dist-info/entry_points.txt,sha256=O4inBeR_cfncBFSCr5VcQUEwGMD7yKlcRQRwU-p6y0Y,43
|
|
23
|
+
iridet_bot-0.1.1a1.dist-info/top_level.txt,sha256=byR3qpK9YFZen-PvnWbZNMIkq7pvuzmVlhLcTmePkYA,7
|
|
24
|
+
iridet_bot-0.1.1a1.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
iribot
|