meadows-bot 0.1.0__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.
- meadows_bot-0.1.0/.env.example +10 -0
- meadows_bot-0.1.0/.gitignore +20 -0
- meadows_bot-0.1.0/Dockerfile +11 -0
- meadows_bot-0.1.0/PKG-INFO +137 -0
- meadows_bot-0.1.0/README.md +112 -0
- meadows_bot-0.1.0/captain-hooks/backup_files.sh +4 -0
- meadows_bot-0.1.0/captain-hooks/restore_files.sh +4 -0
- meadows_bot-0.1.0/docker-compose.yml +23 -0
- meadows_bot-0.1.0/docs/.gitkeep +0 -0
- meadows_bot-0.1.0/pyproject.toml +86 -0
- meadows_bot-0.1.0/src/meadows/bot/__about__.py +3 -0
- meadows_bot-0.1.0/src/meadows/bot/__init__.py +37 -0
- meadows_bot-0.1.0/src/meadows/bot/base.py +972 -0
- meadows_bot-0.1.0/src/meadows/bot/chat_bot.py +203 -0
- meadows_bot-0.1.0/src/meadows/bot/examples/__init__.py +7 -0
- meadows_bot-0.1.0/src/meadows/bot/examples/dependent_bot.py +72 -0
- meadows_bot-0.1.0/src/meadows/bot/examples/echo_bot.py +99 -0
- meadows_bot-0.1.0/src/meadows/bot/examples/echo_service_bot.py +118 -0
- meadows_bot-0.1.0/src/meadows/bot/examples/label_listener_bot.py +137 -0
- meadows_bot-0.1.0/src/meadows/bot/examples/math_service_bot.py +149 -0
- meadows_bot-0.1.0/src/meadows/bot/examples/rpc_caller_bot.py +162 -0
- meadows_bot-0.1.0/src/meadows/bot/examples/sentiment_bot.py +166 -0
- meadows_bot-0.1.0/src/meadows/bot/examples/todo_bot.py +331 -0
- meadows_bot-0.1.0/src/meadows/bot/export_bot.py +139 -0
- meadows_bot-0.1.0/src/meadows/bot/fetch_bot.py +288 -0
- meadows_bot-0.1.0/src/meadows/bot/help_bot.py +101 -0
- meadows_bot-0.1.0/src/meadows/bot/llm.py +127 -0
- meadows_bot-0.1.0/src/meadows/bot/rag_bot.py +196 -0
- meadows_bot-0.1.0/src/meadows/bot/slo_bot.py +209 -0
- meadows_bot-0.1.0/src/meadows/bot/stats_bot.py +290 -0
- meadows_bot-0.1.0/start.sh +2 -0
- meadows_bot-0.1.0/tasks.py +66 -0
- meadows_bot-0.1.0/tests/conftest.py +186 -0
- meadows_bot-0.1.0/tests/test_base.py +662 -0
- meadows_bot-0.1.0/tests/test_call_rpc.py +226 -0
- meadows_bot-0.1.0/tests/test_chat_bot.py +154 -0
- meadows_bot-0.1.0/tests/test_echo.py +153 -0
- meadows_bot-0.1.0/tests/test_echo_service_bot.py +110 -0
- meadows_bot-0.1.0/tests/test_export_bot.py +133 -0
- meadows_bot-0.1.0/tests/test_fetch_bot.py +157 -0
- meadows_bot-0.1.0/tests/test_help_bot.py +83 -0
- meadows_bot-0.1.0/tests/test_label_listener_bot.py +153 -0
- meadows_bot-0.1.0/tests/test_llm.py +111 -0
- meadows_bot-0.1.0/tests/test_math_service_bot.py +109 -0
- meadows_bot-0.1.0/tests/test_rag_bot.py +148 -0
- meadows_bot-0.1.0/tests/test_rpc_caller_bot.py +111 -0
- meadows_bot-0.1.0/tests/test_sentiment_bot.py +151 -0
- meadows_bot-0.1.0/tests/test_slo_bot.py +157 -0
- meadows_bot-0.1.0/tests/test_stats_bot.py +120 -0
- meadows_bot-0.1.0/uv.lock +2006 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Meadows server URL (the hub this bot connects to)
|
|
2
|
+
MEADOWS_SERVER_URL=http://localhost:8080
|
|
3
|
+
|
|
4
|
+
# Pre-signed JWT token for this bot.
|
|
5
|
+
# Only the server knows the signing key. Generate this token with:
|
|
6
|
+
# cd meadows-server && inv bot-jwt --name=<bot_name> --expiry=1y
|
|
7
|
+
MEADOWS_JWT_TOKEN=
|
|
8
|
+
|
|
9
|
+
# Seconds to wait before disconnecting after an auth error (avoids reconnect loops)
|
|
10
|
+
BOT_AUTH_ERROR_DISCONNECT_DELAY=5
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
FROM python:3.13-slim
|
|
2
|
+
|
|
3
|
+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
|
|
4
|
+
|
|
5
|
+
WORKDIR /app
|
|
6
|
+
COPY pyproject.toml .
|
|
7
|
+
COPY src/ ./src/
|
|
8
|
+
COPY README.md .
|
|
9
|
+
RUN uv pip install --system --no-cache .
|
|
10
|
+
|
|
11
|
+
CMD ["python", "-c", "import meadows.bot; print('meadows-bot', meadows.bot.__version__)"]
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: meadows-bot
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MEADOWS bot SDK: BaseBot, LLMBot. Bot-author-facing package with fast quick-start.
|
|
5
|
+
Author: MEADOWS
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
8
|
+
Requires-Dist: meadows-client
|
|
9
|
+
Requires-Dist: meadows-protocol
|
|
10
|
+
Provides-Extra: dependency-heavy
|
|
11
|
+
Requires-Dist: beautifulsoup4>=4.12.0; extra == 'dependency-heavy'
|
|
12
|
+
Requires-Dist: html2text>=2024.2.26; extra == 'dependency-heavy'
|
|
13
|
+
Requires-Dist: httpx>=0.28.0; extra == 'dependency-heavy'
|
|
14
|
+
Requires-Dist: trafilatura>=2.0.0; extra == 'dependency-heavy'
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: hatch; extra == 'dev'
|
|
17
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
18
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
|
|
19
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
20
|
+
Requires-Dist: ruff==0.14.9; extra == 'dev'
|
|
21
|
+
Provides-Extra: examples
|
|
22
|
+
Provides-Extra: llm
|
|
23
|
+
Requires-Dist: httpx>=0.28.0; extra == 'llm'
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# meadows-bot
|
|
27
|
+
|
|
28
|
+
> MEADOWS bot SDK: `BaseBot`, `LLMBot`, and ready-to-use bots. Bot-author-facing package with a fast quick-start.
|
|
29
|
+
> Depends on `meadows-client` (transport) and `meadows-protocol` (shapes). Never imports from `meadows-server`.
|
|
30
|
+
|
|
31
|
+
## What this package contains
|
|
32
|
+
|
|
33
|
+
- `base.py` — `BaseBot`: the SDK core. Auth, reconnect, registration, routing are hidden.
|
|
34
|
+
- `llm.py` — `LLMBot`: minimal abstract LLM bot (no provider specifics in the PoC).
|
|
35
|
+
- `examples/echo_bot.py` — the canonical example bot.
|
|
36
|
+
- Ready-to-use bots (lazy-loaded via `from meadows.bot import HelpBot`, etc.):
|
|
37
|
+
- `help_bot.py` — static help text (`help`, `bots`, `commands`, `groups`, `guide`)
|
|
38
|
+
- `stats_bot.py` — passive monitoring dashboard (`@stats`, `@stats reset`)
|
|
39
|
+
- `chat_bot.py` — LLM conversational assistant via Ollama
|
|
40
|
+
- `fetch_bot.py` — fetches URLs and converts to Markdown
|
|
41
|
+
- `export_bot.py` — exports a thread to a Markdown file
|
|
42
|
+
- `rag_bot.py` — video/audio fragment search via RAG API
|
|
43
|
+
- `slo_bot.py` — Dutch SLO curriculum learning outcome search
|
|
44
|
+
|
|
45
|
+
## Quick start
|
|
46
|
+
|
|
47
|
+
A working bot is `BOT_NAME` + `should_handle` + `handle` + `connect()`. That's the whole contract.
|
|
48
|
+
|
|
49
|
+
Set the `MEADOWS_JWT_TOKEN` env var (generate with `cd meadows-server && inv bot-jwt --name=mybot --expiry=1y`), then:
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from meadows.bot import BaseBot
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class MyBot(BaseBot):
|
|
56
|
+
BOT_NAME = "mybot"
|
|
57
|
+
BOT_DESCRIPTION = "My custom bot"
|
|
58
|
+
BOT_COMMANDS = [{"name": "greet", "description": "Say hello"}]
|
|
59
|
+
|
|
60
|
+
def should_handle(self, command, args):
|
|
61
|
+
return command == "greet"
|
|
62
|
+
|
|
63
|
+
def handle(self, command, args, raw_args, message, thread_context):
|
|
64
|
+
return f"Hello {args[0] if args else 'user'}!"
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
if __name__ == "__main__":
|
|
68
|
+
MyBot().connect()
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Install
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
cd meadows-bot
|
|
75
|
+
uv pip install -e .
|
|
76
|
+
|
|
77
|
+
# With extra bots that need HTTP dependencies
|
|
78
|
+
uv pip install -e ".[examples,dependency-heavy,llm]"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Test
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
uv run pytest -q
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Included bots
|
|
88
|
+
|
|
89
|
+
### Production bots (lazy-loaded via `from meadows.bot import HelpBot`)
|
|
90
|
+
|
|
91
|
+
| Bot | Commands | Deps | Description |
|
|
92
|
+
|-----|----------|------|-------------|
|
|
93
|
+
| `HelpBot` | `help`, `bots`, `commands`, `groups`, `guide` | none | Static help text |
|
|
94
|
+
| `StatsBot` | `@stats`, `@stats reset`, `@stats groups`, `@stats top`, `@stats help` | none | Passive monitoring dashboard; observes all traffic |
|
|
95
|
+
| `ChatBot` | `chat`, `ask`, `vraag`, `praat` | `[llm]` | LLM assistant via Ollama (requires `OLLAMA_URL`) |
|
|
96
|
+
| `FetchBot` | `fetch`, `haal` | `[dependency-heavy]` | Fetches URLs → Markdown |
|
|
97
|
+
| `ExportBot` | `export`, `exporteer` | none | Exports a thread to a Markdown file |
|
|
98
|
+
| `RagBot` | `rag`, `zoek` | none | Video/audio fragment search via RAG API |
|
|
99
|
+
| `SLOBot` | `slo`, `leerdoel` | none | Dutch SLO curriculum learning outcome search |
|
|
100
|
+
|
|
101
|
+
### Example bots (in `examples/` directory)
|
|
102
|
+
|
|
103
|
+
| Bot | Description |
|
|
104
|
+
|-----|-------------|
|
|
105
|
+
| `EchoBot` | Canonical example bot — echoes messages back |
|
|
106
|
+
| `SentimentBot` | Label producer: sentiment analysis on all messages |
|
|
107
|
+
| `LabelListenerBot` | Label consumer: alerts on angry sentiment |
|
|
108
|
+
| `EchoServiceBot` | Minimal RPC service (echo) |
|
|
109
|
+
| `MathServiceBot` | RPC service (arithmetic) |
|
|
110
|
+
| `RPCCallerBot` | Demonstrates RPC via labels |
|
|
111
|
+
| `TodoBot` | CRUD demo using interactive forms |
|
|
112
|
+
|
|
113
|
+
## The protocol boundary
|
|
114
|
+
|
|
115
|
+
> The system contracts what it itself must understand. What only bots and humans need to understand stays opaque.
|
|
116
|
+
|
|
117
|
+
This package imports from `meadows.client` (transport) and `meadows.protocol` (shapes), never from `meadows.server`. Server and bot meet only via the protocol declaration. If you find yourself wanting an import from `meadows.server`, something has gone wrong — that belongs in `meadows.protocol` or nowhere.
|
|
118
|
+
|
|
119
|
+
## Bot-author surface
|
|
120
|
+
|
|
121
|
+
| What | How |
|
|
122
|
+
|---|---|
|
|
123
|
+
| Identity | `BOT_NAME`, `BOT_DESCRIPTION`, `BOT_COMMANDS`, `BOT_CONTEXT_LIMIT` (class attrs) |
|
|
124
|
+
| Decide | `should_handle(command, args) -> bool` (abstract) |
|
|
125
|
+
| Respond | `handle(command, args, raw_args, message, thread_context) -> str \| None` (abstract) |
|
|
126
|
+
| Start | `connect()` — waits 3s for the server, then connects and blocks |
|
|
127
|
+
| Helpers | `log()`, `get_sender_info()`, `format_help_response()`, `extract_quoted_string()` |
|
|
128
|
+
| Patterns | `register_pattern()`, `unregister_pattern()`, `on_pattern_matched()` (decorator) |
|
|
129
|
+
| Labels | `register_label_subscription()`, `unregister_label_subscription()`, `on_label_assigned()`, `emit_label()` |
|
|
130
|
+
| Forms | `send_form()` — send interactive HTML forms, receive submissions via label subscriptions |
|
|
131
|
+
| RPC | `call_rpc()`, `emit_rpc_request()`, `emit_rpc_response()`, `on_rpc_response()` |
|
|
132
|
+
| History | `fetch_messages()` |
|
|
133
|
+
| Lifecycle hooks | `on_connect()`, `on_disconnect()` (passthrough to client) |
|
|
134
|
+
|
|
135
|
+
## Defaults and errors are pedagogy
|
|
136
|
+
|
|
137
|
+
The target user is not a standard Python developer — it's a Dutch teacher (groep 6) working with an AI during a hackathon. Defaults that "just work" and errors in human language matter more than elegance. A bot that fails silently teaches nothing.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# meadows-bot
|
|
2
|
+
|
|
3
|
+
> MEADOWS bot SDK: `BaseBot`, `LLMBot`, and ready-to-use bots. Bot-author-facing package with a fast quick-start.
|
|
4
|
+
> Depends on `meadows-client` (transport) and `meadows-protocol` (shapes). Never imports from `meadows-server`.
|
|
5
|
+
|
|
6
|
+
## What this package contains
|
|
7
|
+
|
|
8
|
+
- `base.py` — `BaseBot`: the SDK core. Auth, reconnect, registration, routing are hidden.
|
|
9
|
+
- `llm.py` — `LLMBot`: minimal abstract LLM bot (no provider specifics in the PoC).
|
|
10
|
+
- `examples/echo_bot.py` — the canonical example bot.
|
|
11
|
+
- Ready-to-use bots (lazy-loaded via `from meadows.bot import HelpBot`, etc.):
|
|
12
|
+
- `help_bot.py` — static help text (`help`, `bots`, `commands`, `groups`, `guide`)
|
|
13
|
+
- `stats_bot.py` — passive monitoring dashboard (`@stats`, `@stats reset`)
|
|
14
|
+
- `chat_bot.py` — LLM conversational assistant via Ollama
|
|
15
|
+
- `fetch_bot.py` — fetches URLs and converts to Markdown
|
|
16
|
+
- `export_bot.py` — exports a thread to a Markdown file
|
|
17
|
+
- `rag_bot.py` — video/audio fragment search via RAG API
|
|
18
|
+
- `slo_bot.py` — Dutch SLO curriculum learning outcome search
|
|
19
|
+
|
|
20
|
+
## Quick start
|
|
21
|
+
|
|
22
|
+
A working bot is `BOT_NAME` + `should_handle` + `handle` + `connect()`. That's the whole contract.
|
|
23
|
+
|
|
24
|
+
Set the `MEADOWS_JWT_TOKEN` env var (generate with `cd meadows-server && inv bot-jwt --name=mybot --expiry=1y`), then:
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from meadows.bot import BaseBot
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class MyBot(BaseBot):
|
|
31
|
+
BOT_NAME = "mybot"
|
|
32
|
+
BOT_DESCRIPTION = "My custom bot"
|
|
33
|
+
BOT_COMMANDS = [{"name": "greet", "description": "Say hello"}]
|
|
34
|
+
|
|
35
|
+
def should_handle(self, command, args):
|
|
36
|
+
return command == "greet"
|
|
37
|
+
|
|
38
|
+
def handle(self, command, args, raw_args, message, thread_context):
|
|
39
|
+
return f"Hello {args[0] if args else 'user'}!"
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
if __name__ == "__main__":
|
|
43
|
+
MyBot().connect()
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Install
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
cd meadows-bot
|
|
50
|
+
uv pip install -e .
|
|
51
|
+
|
|
52
|
+
# With extra bots that need HTTP dependencies
|
|
53
|
+
uv pip install -e ".[examples,dependency-heavy,llm]"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Test
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
uv run pytest -q
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Included bots
|
|
63
|
+
|
|
64
|
+
### Production bots (lazy-loaded via `from meadows.bot import HelpBot`)
|
|
65
|
+
|
|
66
|
+
| Bot | Commands | Deps | Description |
|
|
67
|
+
|-----|----------|------|-------------|
|
|
68
|
+
| `HelpBot` | `help`, `bots`, `commands`, `groups`, `guide` | none | Static help text |
|
|
69
|
+
| `StatsBot` | `@stats`, `@stats reset`, `@stats groups`, `@stats top`, `@stats help` | none | Passive monitoring dashboard; observes all traffic |
|
|
70
|
+
| `ChatBot` | `chat`, `ask`, `vraag`, `praat` | `[llm]` | LLM assistant via Ollama (requires `OLLAMA_URL`) |
|
|
71
|
+
| `FetchBot` | `fetch`, `haal` | `[dependency-heavy]` | Fetches URLs → Markdown |
|
|
72
|
+
| `ExportBot` | `export`, `exporteer` | none | Exports a thread to a Markdown file |
|
|
73
|
+
| `RagBot` | `rag`, `zoek` | none | Video/audio fragment search via RAG API |
|
|
74
|
+
| `SLOBot` | `slo`, `leerdoel` | none | Dutch SLO curriculum learning outcome search |
|
|
75
|
+
|
|
76
|
+
### Example bots (in `examples/` directory)
|
|
77
|
+
|
|
78
|
+
| Bot | Description |
|
|
79
|
+
|-----|-------------|
|
|
80
|
+
| `EchoBot` | Canonical example bot — echoes messages back |
|
|
81
|
+
| `SentimentBot` | Label producer: sentiment analysis on all messages |
|
|
82
|
+
| `LabelListenerBot` | Label consumer: alerts on angry sentiment |
|
|
83
|
+
| `EchoServiceBot` | Minimal RPC service (echo) |
|
|
84
|
+
| `MathServiceBot` | RPC service (arithmetic) |
|
|
85
|
+
| `RPCCallerBot` | Demonstrates RPC via labels |
|
|
86
|
+
| `TodoBot` | CRUD demo using interactive forms |
|
|
87
|
+
|
|
88
|
+
## The protocol boundary
|
|
89
|
+
|
|
90
|
+
> The system contracts what it itself must understand. What only bots and humans need to understand stays opaque.
|
|
91
|
+
|
|
92
|
+
This package imports from `meadows.client` (transport) and `meadows.protocol` (shapes), never from `meadows.server`. Server and bot meet only via the protocol declaration. If you find yourself wanting an import from `meadows.server`, something has gone wrong — that belongs in `meadows.protocol` or nowhere.
|
|
93
|
+
|
|
94
|
+
## Bot-author surface
|
|
95
|
+
|
|
96
|
+
| What | How |
|
|
97
|
+
|---|---|
|
|
98
|
+
| Identity | `BOT_NAME`, `BOT_DESCRIPTION`, `BOT_COMMANDS`, `BOT_CONTEXT_LIMIT` (class attrs) |
|
|
99
|
+
| Decide | `should_handle(command, args) -> bool` (abstract) |
|
|
100
|
+
| Respond | `handle(command, args, raw_args, message, thread_context) -> str \| None` (abstract) |
|
|
101
|
+
| Start | `connect()` — waits 3s for the server, then connects and blocks |
|
|
102
|
+
| Helpers | `log()`, `get_sender_info()`, `format_help_response()`, `extract_quoted_string()` |
|
|
103
|
+
| Patterns | `register_pattern()`, `unregister_pattern()`, `on_pattern_matched()` (decorator) |
|
|
104
|
+
| Labels | `register_label_subscription()`, `unregister_label_subscription()`, `on_label_assigned()`, `emit_label()` |
|
|
105
|
+
| Forms | `send_form()` — send interactive HTML forms, receive submissions via label subscriptions |
|
|
106
|
+
| RPC | `call_rpc()`, `emit_rpc_request()`, `emit_rpc_response()`, `on_rpc_response()` |
|
|
107
|
+
| History | `fetch_messages()` |
|
|
108
|
+
| Lifecycle hooks | `on_connect()`, `on_disconnect()` (passthrough to client) |
|
|
109
|
+
|
|
110
|
+
## Defaults and errors are pedagogy
|
|
111
|
+
|
|
112
|
+
The target user is not a standard Python developer — it's a Dutch teacher (groep 6) working with an AI during a hackathon. Defaults that "just work" and errors in human language matter more than elegance. A bot that fails silently teaches nothing.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
networks:
|
|
2
|
+
meadows:
|
|
3
|
+
driver: bridge
|
|
4
|
+
broker:
|
|
5
|
+
external: true
|
|
6
|
+
name: broker
|
|
7
|
+
|
|
8
|
+
services:
|
|
9
|
+
meadows-bot:
|
|
10
|
+
build: .
|
|
11
|
+
image: meadows-bot:latest
|
|
12
|
+
restart: unless-stopped
|
|
13
|
+
environment:
|
|
14
|
+
- MEADOWS_SERVER_URL=${MEADOWS_SERVER_URL:-http://localhost:8080}
|
|
15
|
+
- MEADOWS_JWT_TOKEN=${MEADOWS_JWT_TOKEN}
|
|
16
|
+
- BOT_AUTH_ERROR_DISCONNECT_DELAY=${BOT_AUTH_ERROR_DISCONNECT_DELAY:-5}
|
|
17
|
+
networks:
|
|
18
|
+
- meadows
|
|
19
|
+
logging:
|
|
20
|
+
driver: "json-file"
|
|
21
|
+
options:
|
|
22
|
+
max-size: "100m"
|
|
23
|
+
max-file: "5"
|
|
File without changes
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "meadows-bot"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "MEADOWS bot SDK: BaseBot, LLMBot. Bot-author-facing package with fast quick-start."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
license-expression = "MIT"
|
|
12
|
+
authors = [{ name = "MEADOWS" }]
|
|
13
|
+
dependencies = [
|
|
14
|
+
"meadows-protocol",
|
|
15
|
+
"meadows-client",
|
|
16
|
+
"aiohttp>=3.9.0",
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.optional-dependencies]
|
|
20
|
+
examples = []
|
|
21
|
+
dependency-heavy = ["httpx>=0.28.0", "trafilatura>=2.0.0", "beautifulsoup4>=4.12.0", "html2text>=2024.2.26"]
|
|
22
|
+
llm = ["httpx>=0.28.0"]
|
|
23
|
+
dev = ["hatch", "pytest>=8.0.0", "pytest-asyncio>=0.23.0", "pytest-cov>=5.0.0", "ruff==0.14.9"]
|
|
24
|
+
|
|
25
|
+
[tool.hatch.build.targets.wheel]
|
|
26
|
+
packages = ["src/meadows"]
|
|
27
|
+
|
|
28
|
+
[tool.uv.sources]
|
|
29
|
+
meadows-protocol = { path = "../meadows-protocol", editable = true }
|
|
30
|
+
meadows-client = { path = "../meadows-client", editable = true }
|
|
31
|
+
|
|
32
|
+
[tool.ruff]
|
|
33
|
+
target-version = "py312"
|
|
34
|
+
line-length = 120
|
|
35
|
+
|
|
36
|
+
[tool.ruff.lint]
|
|
37
|
+
select = ["F", "E", "W", "Q", "A", "SIM", "ARG", "PTH", "RUF", "C90", "N", "YTT"]
|
|
38
|
+
|
|
39
|
+
[tool.pytest.ini_options]
|
|
40
|
+
testpaths = ["tests"]
|
|
41
|
+
asyncio_mode = "auto"
|
|
42
|
+
|
|
43
|
+
[tool.vommit]
|
|
44
|
+
allow_breaking_bang = true
|
|
45
|
+
allow_breaking_footer = true
|
|
46
|
+
prerelease_token = "rc"
|
|
47
|
+
confirm = true
|
|
48
|
+
|
|
49
|
+
[tool.vommit.git]
|
|
50
|
+
enabled = true
|
|
51
|
+
origin = "origin"
|
|
52
|
+
branch = "main"
|
|
53
|
+
on_wrong_branch = "error"
|
|
54
|
+
tag_format = "v{version}"
|
|
55
|
+
commit_format = "{version}"
|
|
56
|
+
|
|
57
|
+
[tool.vommit.changelog]
|
|
58
|
+
enabled = true
|
|
59
|
+
file = "CHANGELOG.md"
|
|
60
|
+
include_prereleases = false
|
|
61
|
+
placeholder = "<!-- next-version-placeholder -->"
|
|
62
|
+
placeholder_regex = "<auto>"
|
|
63
|
+
entry_title_format = "## v{version} ({date:%Y-%m-%d})"
|
|
64
|
+
|
|
65
|
+
[tool.vommit.changelog.levels]
|
|
66
|
+
break = "Breaking Change{s}"
|
|
67
|
+
feat = "Feature{s}"
|
|
68
|
+
fix = "Fix{es}"
|
|
69
|
+
perf = "Performance"
|
|
70
|
+
docs = "Documentation"
|
|
71
|
+
|
|
72
|
+
[tool.vommit.pypi]
|
|
73
|
+
enabled = true
|
|
74
|
+
use_keyring = true
|
|
75
|
+
|
|
76
|
+
[tool.vommit.commands]
|
|
77
|
+
clean = "rm -rf ./dist"
|
|
78
|
+
build = "uv build"
|
|
79
|
+
publish = "../pypi-publish"
|
|
80
|
+
post_publish = ""
|
|
81
|
+
|
|
82
|
+
[tool.vommit.version_bump_map]
|
|
83
|
+
break = "major"
|
|
84
|
+
feat = "minor"
|
|
85
|
+
fix = "patch"
|
|
86
|
+
perf = "patch"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""MEADOWS bot SDK.
|
|
2
|
+
|
|
3
|
+
BUSINESS RULE (MEADOWS §5 line 131): Document for AI use, because an AI
|
|
4
|
+
writes alongside humans. The existing bot-development-guide.md is the
|
|
5
|
+
pattern to continue: example-first, copy-pasteable, dense tables.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from meadows.bot.__about__ import __version__
|
|
9
|
+
from meadows.bot.base import BaseBot
|
|
10
|
+
from meadows.bot.llm import LLMBot
|
|
11
|
+
|
|
12
|
+
__all__ = ["BaseBot", "LLMBot", "__version__"]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def __getattr__(name):
|
|
16
|
+
if name == "HelpBot":
|
|
17
|
+
from meadows.bot.help_bot import HelpBot
|
|
18
|
+
return HelpBot
|
|
19
|
+
if name == "StatsBot":
|
|
20
|
+
from meadows.bot.stats_bot import StatsBot
|
|
21
|
+
return StatsBot
|
|
22
|
+
if name == "RagBot":
|
|
23
|
+
from meadows.bot.rag_bot import RagBot
|
|
24
|
+
return RagBot
|
|
25
|
+
if name == "SLOBot":
|
|
26
|
+
from meadows.bot.slo_bot import SLOBot
|
|
27
|
+
return SLOBot
|
|
28
|
+
if name == "FetchBot":
|
|
29
|
+
from meadows.bot.fetch_bot import FetchBot
|
|
30
|
+
return FetchBot
|
|
31
|
+
if name == "ExportBot":
|
|
32
|
+
from meadows.bot.export_bot import ExportBot
|
|
33
|
+
return ExportBot
|
|
34
|
+
if name == "ChatBot":
|
|
35
|
+
from meadows.bot.chat_bot import ChatBot
|
|
36
|
+
return ChatBot
|
|
37
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|