chore: release 1.0.0
Bump version to 1.0.0 and pin the donglora dep to >=1.0.0,<2.0.0 (PyPI), matching the freshly-published donglora 1.0.0 client. Also knock out two preexisting lint failures surfaced by the release-time `just check` gauntlet: * orac/crypto.py: drop the redundant int() wrap around round() (RUF046). * orac/state.py: widen _state value type to include list[list[float]] so heard_positions type-checks under pyright.
This commit is contained in:
5 files changed
+35
-7
No files matched your search
@@ -0,0 +1,28 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## 1.0.0 — 2026-04-22
|
||||||
|
|
||||||
|
Initial public release. Orac is a MeshCore chatbot that uses the
|
||||||
|
`donglora` client to bridge a LoRa dongle to an Anthropic model.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- `BotRuntime` orchestrating IO, worker, and log threads against a
|
||||||
|
`donglora.Dongle` instance.
|
||||||
|
- ADVERT scheduler with IQR-trimmed mean position derived from heard
|
||||||
|
repeater adverts.
|
||||||
|
- Typed `TxQueue` with retry / ack tracking against MeshCore message
|
||||||
|
IDs.
|
||||||
|
- DM reply pipeline that calls Claude off the IO loop and enqueues
|
||||||
|
reply packets at the right priority.
|
||||||
|
- Structured JSONL event log at `~/.donglora/orac-events.jsonl`.
|
||||||
|
- `just run` / `just check` / `just events` developer ergonomics.
|
||||||
|
- `donglora>=1.0.0,<2.0.0` declared as the registry dep; local dev
|
||||||
|
uses the `[tool.uv.sources]` editable-path override.
|
||||||
|
|
||||||
|
### Notes
|
||||||
|
|
||||||
|
- Not published to PyPI. Installed from a local checkout only; this
|
||||||
|
1.0.0 tag captures the point at which the bot runs against the
|
||||||
|
Protocol v2 stack (`donglora` 1.0 / `donglora-mux` 1.0 /
|
||||||
|
`donglora-protocol` 1.0).
|
||||||
+2
-2
@@ -310,8 +310,8 @@ def build_advert_payload() -> bytes:
|
|||||||
timestamp = struct.pack("<I", int(time.time()))
|
timestamp = struct.pack("<I", int(time.time()))
|
||||||
name_bytes = BOT_NAME.encode("utf-8")
|
name_bytes = BOT_NAME.encode("utf-8")
|
||||||
if heard_position_count() >= 5 and (avg := average_heard_position()) is not None:
|
if heard_position_count() >= 5 and (avg := average_heard_position()) is not None:
|
||||||
lat_i = int(round(avg[0] * 1_000_000))
|
lat_i = round(avg[0] * 1_000_000)
|
||||||
lon_i = int(round(avg[1] * 1_000_000))
|
lon_i = round(avg[1] * 1_000_000)
|
||||||
# flags: has_name (0x80) | has_location (0x10) | chat node (0x01)
|
# flags: has_name (0x80) | has_location (0x10) | chat node (0x01)
|
||||||
app_data = bytes([0x91]) + struct.pack("<ii", lat_i, lon_i) + name_bytes
|
app_data = bytes([0x91]) + struct.pack("<ii", lat_i, lon_i) + name_bytes
|
||||||
else:
|
else:
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ log = logging.getLogger("orac")
|
|||||||
|
|
||||||
# ── Persistent state ─────────────────────────────────────────────
|
# ── Persistent state ─────────────────────────────────────────────
|
||||||
|
|
||||||
_state: dict[str, dict[str, object]] = {
|
_state: dict[str, dict[str, object] | list[list[float]]] = {
|
||||||
"channel_history": {}, # channel_name -> list of messages
|
"channel_history": {}, # channel_name -> list of messages
|
||||||
"dm_history": {}, # peer_pubkey_hex -> list of messages
|
"dm_history": {}, # peer_pubkey_hex -> list of messages
|
||||||
"known_nodes": {}, # pubkey_hex -> {"name": str, "seen": float}
|
"known_nodes": {}, # pubkey_hex -> {"name": str, "seen": float}
|
||||||
|
|||||||
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "donglora-ai-bot"
|
name = "donglora-ai-bot"
|
||||||
version = "0.1.0"
|
version = "1.0.0"
|
||||||
description = "MeshCore AI chatbot — default mesh name 'Orac'"
|
description = "MeshCore AI chatbot — default mesh name 'Orac'"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
authors = [{ name = "Stephen Waits" }]
|
authors = [{ name = "Stephen Waits" }]
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"donglora",
|
"donglora>=1.0.0,<2.0.0",
|
||||||
"anthropic",
|
"anthropic",
|
||||||
"cobs",
|
"cobs",
|
||||||
"pyserial",
|
"pyserial",
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "donglora"
|
name = "donglora"
|
||||||
version = "0.2.0"
|
version = "1.0.0"
|
||||||
source = { editable = "../client-py" }
|
source = { editable = "../client-py" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "cobs" },
|
{ name = "cobs" },
|
||||||
@@ -206,7 +206,7 @@ dev = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "donglora-ai-bot"
|
name = "donglora-ai-bot"
|
||||||
version = "0.1.0"
|
version = "1.0.0"
|
||||||
source = { virtual = "." }
|
source = { virtual = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "anthropic" },
|
{ name = "anthropic" },
|
||||||
|
|||||||
Reference in new issue
Block a user