@artil-ai/hermes 0.1.0 → 0.1.2

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.
package/README.md CHANGED
@@ -1,41 +1,44 @@
1
1
  # @artil-ai/hermes
2
2
 
3
3
  The Artil platform for the [Hermes](https://hermes-agent.nousresearch.com)
4
- gateway. New email and texts to the agent account, and wake-ups from its team,
5
- reach the gateway as notices that `artil internal hermes-channel` prints, from
6
- where it left off; the agent answers them with the `artil` CLI.
4
+ gateway. New email and texts to the agent account, and messages its team sends
5
+ to its Message URL, reach the gateway as notices that
6
+ `artil internal hermes-channel` prints, from where it left off; the agent
7
+ answers them with the `artil` CLI.
7
8
 
8
9
  ## Usage
9
10
 
10
- The `artil` CLI carries the plugin from this package. `artil plugin install
11
- hermes` writes it to `$HERMES_HOME/plugins/artil` and turns it on in Hermes'
12
- `config.yaml`, with the absolute path of `artil`, since the gateway's service
13
- does not see your shell's PATH:
14
-
15
- ```yaml
16
- plugins:
17
- enabled: [artil]
18
- platforms:
19
- artil:
20
- enabled: true
21
- extra:
22
- command: /Users/you/.local/bin/artil
11
+ Install the [Artil CLI](https://artil.dev/INSTALL.md), sign in as the agent with
12
+ `artil auth login`, and let it set up the plugin and the `artil` skill:
13
+
14
+ ```sh
15
+ artil plugin install hermes
16
+ ```
17
+
18
+ Or install the plugin with Hermes:
19
+
20
+ ```sh
21
+ hermes plugins install artilai/plugins/plugins/hermes --enable
23
22
  ```
24
23
 
25
- | Entry point | What it is |
26
- | ------------------- | ------------------------------------------------------- |
27
- | `artil/plugin.yaml` | The plugin manifest; Hermes 0.21.5 or later loads it |
28
- | `artil/__init__.py` | The `artil` gateway platform and its system-prompt hint |
24
+ The gateway runs the `artil` that `platforms.artil.extra.command` names in
25
+ Hermes' `config.yaml`, else the one on its PATH, else `~/.local/bin/artil`. See
26
+ [Hermes](https://docs.artil.dev/hermes) in the docs.
27
+
28
+ While the gateway runs, the plugin keeps `artil internal hermes-channel`
29
+ running, which reaches Artil with the CLI's login. The plugin sends nothing
30
+ itself: the agent answers with `artil` commands.
31
+
32
+ | Entry point | What it is |
33
+ | ------------- | ------------------------------------------------------- |
34
+ | `plugin.yaml` | The plugin manifest; Hermes 0.21.5 or later loads it |
35
+ | `__init__.py` | The `artil` gateway platform and its system-prompt hint |
29
36
 
30
37
  ## Development
31
38
 
32
- From the repository root, lint and format the plugin with
33
- [ruff](https://docs.astral.sh/ruff), then validate and test it inside the Hermes
34
- image:
39
+ From the repository root, lint the plugin with [ruff](https://docs.astral.sh/ruff),
40
+ then validate and test it inside the Hermes image; this needs `uv` and Docker:
35
41
 
36
42
  ```sh
37
- uvx ruff check && uvx ruff format --check
38
- docker run --rm -v "$PWD/hermes:/plugin" -w /plugin --entrypoint hermes nousresearch/hermes-agent:latest plugins validate artil
39
- docker run --rm -v "$PWD/hermes:/plugin" -w /plugin --entrypoint sh nousresearch/hermes-agent:latest -c \
40
- 'uv pip install -q --python /opt/hermes/.venv/bin/python pytest && PYTHONPATH=/opt/hermes /opt/hermes/.venv/bin/python -m pytest -p no:cacheprovider tests'
43
+ bun run check:hermes
41
44
  ```
@@ -5,6 +5,9 @@ from __future__ import annotations
5
5
  import asyncio
6
6
  import dataclasses
7
7
  import json
8
+ import shutil
9
+ import signal
10
+ from pathlib import Path
8
11
  from typing import Any
9
12
 
10
13
  from gateway.config import Platform, PlatformConfig
@@ -14,9 +17,10 @@ from gateway.platforms.base import BasePlatformAdapter, MessageEvent, MessageTyp
14
17
  PLATFORM = "artil"
15
18
 
16
19
  HINT = (
17
- "Notices about new email and texts to this Artil agent account, and wake-ups from its team, "
18
- "arrive here. Read each message with the artil command its notice names, and answer it with "
19
- "`artil email send --reply-to` or `artil sms send --reply-to`, as the artil skill describes. "
20
+ "Notices about new email and texts to this Artil agent account, and messages its team sends "
21
+ "to its Message URL, arrive here. Read each email or text with the artil command its notice "
22
+ "names, and answer it with `artil email send --reply-to` or `artil sms send --reply-to`; a "
23
+ "message from the Message URL comes whole, and its notice says how to answer it. "
20
24
  "Nobody outside reads what you write in this conversation."
21
25
  )
22
26
 
@@ -29,7 +33,10 @@ class ArtilAdapter(BasePlatformAdapter):
29
33
  def __init__(self, config: PlatformConfig) -> None:
30
34
  config.extra = {**(config.extra or {}), "allow_from": [PLATFORM]}
31
35
  super().__init__(config, Platform(PLATFORM))
32
- self._command = str(config.extra.get("command") or "artil")
36
+ # A gateway service may not have the PATH that finds artil where its installer put it.
37
+ self._command = str(
38
+ config.extra.get("command") or shutil.which("artil") or Path.home() / ".local/bin/artil"
39
+ )
33
40
  self._process: asyncio.subprocess.Process | None = None
34
41
  self._listening: asyncio.Task | None = None
35
42
 
@@ -63,7 +70,7 @@ class ArtilAdapter(BasePlatformAdapter):
63
70
 
64
71
  reason = (await problem).decode().strip()
65
72
  code = await process.wait()
66
- asked_to_stop = code in (0, -2, -15)
73
+ asked_to_stop = code in (0, -signal.SIGINT, -signal.SIGTERM)
67
74
 
68
75
  if asked_to_stop:
69
76
  await asyncio.sleep(self.STOP_GRACE_SECONDS)
@@ -134,6 +141,7 @@ def _needs_nothing() -> bool:
134
141
 
135
142
 
136
143
  def _service_fields() -> dict[str, Any]:
144
+ """The entry fields Hermes after 0.21.5 knows, which 0.21.5 itself rejects."""
137
145
  known = {field.name for field in dataclasses.fields(PlatformEntry)}
138
146
  wanted = {"trusted_inbound": True, "display_tier": "minimal"}
139
147
  return {name: value for name, value in wanted.items() if name in known}
package/package.json CHANGED
@@ -1,24 +1,25 @@
1
1
  {
2
2
  "name": "@artil-ai/hermes",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Hear about your Artil agent's new messages in the Hermes gateway, and answer them with the artil CLI.",
5
5
  "keywords": [
6
6
  "artil",
7
7
  "hermes-agent"
8
8
  ],
9
- "homepage": "https://docs.artil.dev/automatic-messages",
9
+ "homepage": "https://docs.artil.dev/hermes",
10
10
  "license": "MIT",
11
11
  "repository": {
12
12
  "type": "git",
13
13
  "url": "git+https://github.com/artilai/plugins.git",
14
- "directory": "hermes"
14
+ "directory": "plugins/hermes"
15
15
  },
16
16
  "files": [
17
- "artil"
17
+ "plugin.yaml",
18
+ "__init__.py"
18
19
  ],
19
20
  "exports": {
20
- "./plugin.yaml": "./artil/plugin.yaml",
21
- "./__init__.py": "./artil/__init__.py"
21
+ "./plugin.yaml": "./plugin.yaml",
22
+ "./__init__.py": "./__init__.py"
22
23
  },
23
24
  "publishConfig": {
24
25
  "access": "public"
package/plugin.yaml ADDED
@@ -0,0 +1,11 @@
1
+ name: artil
2
+ label: Artil
3
+ kind: platform
4
+ version: 0.1.2
5
+ description: >
6
+ New email and texts to an Artil agent account, and messages its team sends to
7
+ its Message URL, reach the Hermes gateway through the artil CLI. The agent
8
+ answers them with the CLI.
9
+ author: Artil
10
+ homepage: https://docs.artil.dev/hermes
11
+ requires_hermes: ">=0.21.5"
package/artil/plugin.yaml DELETED
@@ -1,11 +0,0 @@
1
- name: artil
2
- label: Artil
3
- kind: platform
4
- version: 0.1.0
5
- description: >
6
- New email and texts to an Artil agent account, and wake-ups from its team,
7
- reach the Hermes gateway through the artil CLI. The agent answers them with
8
- the CLI, as the artil skill describes.
9
- author: Artil
10
- homepage: https://docs.artil.dev/automatic-messages
11
- requires_hermes: ">=0.21.5"