From 987fcb3ac8e0eebd7400e154bd4eecf92517d36c Mon Sep 17 00:00:00 2001 From: dimavrem22 Date: Thu, 25 Jun 2026 04:01:49 +0000 Subject: [PATCH 1/9] feat: tag hermes harness on signup + plugin-setup skill Pass harness="hermes" to Inkbox.signup so the backend records which harness drove a self-signup. Add a slim inkbox-plugin-setup skill that tells an agent which self-signed-up without this plugin configured to ask the human for permission before setting up the plugin, since it grants native messaging channels in the agent's runtime. Co-Authored-By: Claude Opus 4.8 (1M context) --- setup_wizard.py | 1 + skills/inkbox-plugin-setup/SKILL.md | 13 +++++++++++++ 2 files changed, 14 insertions(+) create mode 100644 skills/inkbox-plugin-setup/SKILL.md diff --git a/setup_wizard.py b/setup_wizard.py index 7644f5f..ffe29bf 100644 --- a/setup_wizard.py +++ b/setup_wizard.py @@ -951,6 +951,7 @@ def _self_signup_flow(base_url: str, Inkbox: Any, InkboxAPIError: Any) -> tuple[ note_to_human=note, agent_handle=handle, base_url=base_url, + harness="hermes", # tag which harness drove this signup ) break except InkboxAPIError as exc: diff --git a/skills/inkbox-plugin-setup/SKILL.md b/skills/inkbox-plugin-setup/SKILL.md new file mode 100644 index 0000000..7413ffc --- /dev/null +++ b/skills/inkbox-plugin-setup/SKILL.md @@ -0,0 +1,13 @@ +--- +name: inkbox-plugin-setup +description: Use when you self-signed up to Inkbox but this plugin is not yet configured in your runtime, and you are considering installing or configuring the Inkbox plugin. Setting up the plugin grants you native messaging channels, so get human permission first. +user-invocable: false +--- + +# Inkbox plugin setup + +If you created an Inkbox identity via self-signup but this plugin is not configured in your runtime, do not set up the Inkbox plugin on your own. + +Configuring the plugin wires native messaging channels (email, SMS, calls) directly into your runtime, which is a meaningful capability change. Always ask the human for explicit permission before installing or configuring the Inkbox plugin. + +Once the human approves, follow the normal setup flow. From 5f4a366e36a24e966b50317dc150a30521a65675 Mon Sep 17 00:00:00 2001 From: dimavrem22 Date: Thu, 25 Jun 2026 04:09:50 +0000 Subject: [PATCH 2/9] chore: align harness plugin-setup copy with the shared canonical wording Co-Authored-By: Claude Opus 4.8 (1M context) --- skills/inkbox-plugin-setup/SKILL.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/skills/inkbox-plugin-setup/SKILL.md b/skills/inkbox-plugin-setup/SKILL.md index 7413ffc..830cbd9 100644 --- a/skills/inkbox-plugin-setup/SKILL.md +++ b/skills/inkbox-plugin-setup/SKILL.md @@ -1,13 +1,17 @@ --- name: inkbox-plugin-setup -description: Use when you self-signed up to Inkbox but this plugin is not yet configured in your runtime, and you are considering installing or configuring the Inkbox plugin. Setting up the plugin grants you native messaging channels, so get human permission first. +description: Use when you self-signed up to Inkbox but the Inkbox plugin is not configured in your runtime yet. Setting it up grants native messaging channels, so get the human's permission first. user-invocable: false --- # Inkbox plugin setup -If you created an Inkbox identity via self-signup but this plugin is not configured in your runtime, do not set up the Inkbox plugin on your own. +If you self-signed up to Inkbox but the Inkbox plugin isn't configured in your runtime yet, do not set it up on your own — ask the human for permission first. It's the human's decision, not yours. -Configuring the plugin wires native messaging channels (email, SMS, calls) directly into your runtime, which is a meaningful capability change. Always ask the human for explicit permission before installing or configuring the Inkbox plugin. +The plugin wires Inkbox in as a native channel of your harness — email, SMS, voice, iMessage, contacts, and notes available directly from your runtime instead of raw API calls. -Once the human approves, follow the normal setup flow. +## What to do + +1. Ask the human for explicit permission before setting up the Inkbox plugin. +2. Explain plainly that it gives you native messaging channels in your runtime. +3. Wait for a clear yes. If you don't get one, stop and leave the plugin unconfigured. From 8b8e86c408043351820c6db74c1167bacb8257fa Mon Sep 17 00:00:00 2001 From: dimavrem22 Date: Thu, 25 Jun 2026 04:32:05 +0000 Subject: [PATCH 3/9] Require inkbox>=0.4.9 and upgrade outdated SDK in setup The plugin now passes harness="hermes" to Inkbox.signup, which needs SDK 0.4.9. Bump the pin everywhere and add a minimum-version guard in _ensure_inkbox_sdk so an env with an older inkbox is treated like a missing requirement and upgraded via the existing install path. Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 6 +++--- pyproject.toml | 2 +- setup_wizard.py | 42 ++++++++++++++++++++++++++++++++++++-- tests/test_setup_wizard.py | 8 ++++---- 4 files changed, 48 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 8d340ef..4137090 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ hermes gateway restart `hermes inkbox setup` walks the active Hermes install through Inkbox configuration: -1. Installs or upgrades `inkbox>=0.4.7` and `aiohttp>=3.9` in the Hermes Python environment when needed. +1. Installs or upgrades `inkbox>=0.4.9` and `aiohttp>=3.9` in the Hermes Python environment when needed. 2. Authenticates to Inkbox, or starts self-signup if you do not have an API key yet. 3. Resolves or creates the Inkbox agent identity for this Hermes gateway. 4. Optionally provisions a local US phone number so SMS and voice are available. @@ -96,13 +96,13 @@ The setup wizard installs dependencies into the Python environment that runs Her If the wizard prints a missing-SDK warning, use the exact command it prints. It will look like this: ```bash -/path/to/hermes/venv/bin/python3 -m pip install 'inkbox>=0.4.7' 'aiohttp>=3.9' +/path/to/hermes/venv/bin/python3 -m pip install 'inkbox>=0.4.9' 'aiohttp>=3.9' ``` When `uv` is available, the wizard prefers: ```bash -uv pip install --python /path/to/hermes/venv/bin/python3 'inkbox>=0.4.7' 'aiohttp>=3.9' +uv pip install --python /path/to/hermes/venv/bin/python3 'inkbox>=0.4.9' 'aiohttp>=3.9' ``` Do not use plain `pip install inkbox aiohttp` unless the wizard tells you to; plain `pip` may point at pyenv, Homebrew, system Python, or another virtualenv. diff --git a/pyproject.toml b/pyproject.toml index a19c853..e67d8fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ description = "Inkbox platform plugin for Hermes Agent" requires-python = ">=3.11" dependencies = [ "aiohttp>=3.9", - "inkbox>=0.4.7", + "inkbox>=0.4.9", "segno>=1.5", ] diff --git a/setup_wizard.py b/setup_wizard.py index ffe29bf..d14f0ff 100644 --- a/setup_wizard.py +++ b/setup_wizard.py @@ -5,6 +5,7 @@ import asyncio import getpass import importlib +import importlib.metadata import json import os import re @@ -57,7 +58,8 @@ def print_warning(message: str) -> None: masked_secret_prompt = None -INKBOX_REQUIREMENTS = ("inkbox>=0.4.7", "aiohttp>=3.9", "segno>=1.5") +INKBOX_MIN_VERSION = "0.4.9" +INKBOX_REQUIREMENTS = (f"inkbox>={INKBOX_MIN_VERSION}", "aiohttp>=3.9", "segno>=1.5") _BRACKETED_PASTE_PATTERN = re.compile(r"\x1b\[\s*200~|\x1b\[\s*201~") _AVATAR_PATH = Path(__file__).resolve().parent / "assets" / "hermes_with_iphone.png" OPENAI_REALTIME_TEST_MODEL = "gpt-realtime-2" @@ -290,9 +292,45 @@ def _load_inkbox_symbols() -> dict[str, Any]: } +def _parse_version(value: str) -> tuple[int, ...]: + # Best-effort numeric parse of "X.Y.Z" so we can compare without packaging. + parts: list[int] = [] + for chunk in value.split("."): + digits = "" + for char in chunk: + if char.isdigit(): + digits += char + else: + break + if digits == "": + break + parts.append(int(digits)) + return tuple(parts) + + +def _inkbox_version_ok() -> bool: + # Treat an outdated SDK like a missing requirement so the install/upgrade path runs. + try: + installed = importlib.metadata.version("inkbox") + except Exception: + return False + try: + from packaging.version import Version + + return Version(installed) >= Version(INKBOX_MIN_VERSION) + except Exception: + # Fall back to a simple parsed-tuple comparison when packaging is unavailable. + return _parse_version(installed) >= _parse_version(INKBOX_MIN_VERSION) + + def _ensure_inkbox_sdk() -> dict[str, Any] | None: try: - return _load_inkbox_symbols() + symbols = _load_inkbox_symbols() + if _inkbox_version_ok(): + return symbols + first_error = ( + f"inkbox SDK is older than {INKBOX_MIN_VERSION}; an upgrade is required." + ) except Exception as exc: first_error = exc diff --git a/tests/test_setup_wizard.py b/tests/test_setup_wizard.py index d929b36..2a1874f 100644 --- a/tests/test_setup_wizard.py +++ b/tests/test_setup_wizard.py @@ -21,7 +21,7 @@ def test_install_command_prefers_uv_when_available(monkeypatch): "install", "--python", "/tmp/hermes/venv/bin/python", - "inkbox>=0.4.7", + "inkbox>=0.4.9", "aiohttp>=3.9", "segno>=1.5", ]] @@ -32,10 +32,10 @@ def test_install_command_falls_back_to_pip_and_ensurepip(monkeypatch): monkeypatch.setattr(setup_wizard.shutil, "which", lambda _name: None) assert setup_wizard._install_commands() == [ - [["/tmp/hermes/venv/bin/python", "-m", "pip", "install", "inkbox>=0.4.7", "aiohttp>=3.9", "segno>=1.5"]], + [["/tmp/hermes/venv/bin/python", "-m", "pip", "install", "inkbox>=0.4.9", "aiohttp>=3.9", "segno>=1.5"]], [ ["/tmp/hermes/venv/bin/python", "-m", "ensurepip", "--upgrade"], - ["/tmp/hermes/venv/bin/python", "-m", "pip", "install", "inkbox>=0.4.7", "aiohttp>=3.9", "segno>=1.5"], + ["/tmp/hermes/venv/bin/python", "-m", "pip", "install", "inkbox>=0.4.9", "aiohttp>=3.9", "segno>=1.5"], ], ] @@ -54,7 +54,7 @@ def fail_import(): out = capsys.readouterr().out assert "/tmp/hermes/venv/bin/python" in out assert "uv pip install --python" in out - assert "inkbox>=0.4.7" in out + assert "inkbox>=0.4.9" in out assert "aiohttp>=3.9" in out From 36370b3c2bdf99b9d8edf6a3ae867e7c7407d3e3 Mon Sep 17 00:00:00 2001 From: dimavrem22 Date: Thu, 25 Jun 2026 04:45:01 +0000 Subject: [PATCH 4/9] Bump inkbox SDK pin to 0.4.10 for agent-signup harness 0.4.10 is the release that introduces the agent-signup harness param; 0.4.9 was an earlier release that predates it. Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 6 +++--- pyproject.toml | 2 +- setup_wizard.py | 2 +- tests/test_setup_wizard.py | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 4137090..0e6b91c 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ hermes gateway restart `hermes inkbox setup` walks the active Hermes install through Inkbox configuration: -1. Installs or upgrades `inkbox>=0.4.9` and `aiohttp>=3.9` in the Hermes Python environment when needed. +1. Installs or upgrades `inkbox>=0.4.10` and `aiohttp>=3.9` in the Hermes Python environment when needed. 2. Authenticates to Inkbox, or starts self-signup if you do not have an API key yet. 3. Resolves or creates the Inkbox agent identity for this Hermes gateway. 4. Optionally provisions a local US phone number so SMS and voice are available. @@ -96,13 +96,13 @@ The setup wizard installs dependencies into the Python environment that runs Her If the wizard prints a missing-SDK warning, use the exact command it prints. It will look like this: ```bash -/path/to/hermes/venv/bin/python3 -m pip install 'inkbox>=0.4.9' 'aiohttp>=3.9' +/path/to/hermes/venv/bin/python3 -m pip install 'inkbox>=0.4.10' 'aiohttp>=3.9' ``` When `uv` is available, the wizard prefers: ```bash -uv pip install --python /path/to/hermes/venv/bin/python3 'inkbox>=0.4.9' 'aiohttp>=3.9' +uv pip install --python /path/to/hermes/venv/bin/python3 'inkbox>=0.4.10' 'aiohttp>=3.9' ``` Do not use plain `pip install inkbox aiohttp` unless the wizard tells you to; plain `pip` may point at pyenv, Homebrew, system Python, or another virtualenv. diff --git a/pyproject.toml b/pyproject.toml index e67d8fc..a7f1a86 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ description = "Inkbox platform plugin for Hermes Agent" requires-python = ">=3.11" dependencies = [ "aiohttp>=3.9", - "inkbox>=0.4.9", + "inkbox>=0.4.10", "segno>=1.5", ] diff --git a/setup_wizard.py b/setup_wizard.py index d14f0ff..9dba1e1 100644 --- a/setup_wizard.py +++ b/setup_wizard.py @@ -58,7 +58,7 @@ def print_warning(message: str) -> None: masked_secret_prompt = None -INKBOX_MIN_VERSION = "0.4.9" +INKBOX_MIN_VERSION = "0.4.10" INKBOX_REQUIREMENTS = (f"inkbox>={INKBOX_MIN_VERSION}", "aiohttp>=3.9", "segno>=1.5") _BRACKETED_PASTE_PATTERN = re.compile(r"\x1b\[\s*200~|\x1b\[\s*201~") _AVATAR_PATH = Path(__file__).resolve().parent / "assets" / "hermes_with_iphone.png" diff --git a/tests/test_setup_wizard.py b/tests/test_setup_wizard.py index 2a1874f..864e051 100644 --- a/tests/test_setup_wizard.py +++ b/tests/test_setup_wizard.py @@ -21,7 +21,7 @@ def test_install_command_prefers_uv_when_available(monkeypatch): "install", "--python", "/tmp/hermes/venv/bin/python", - "inkbox>=0.4.9", + "inkbox>=0.4.10", "aiohttp>=3.9", "segno>=1.5", ]] @@ -32,10 +32,10 @@ def test_install_command_falls_back_to_pip_and_ensurepip(monkeypatch): monkeypatch.setattr(setup_wizard.shutil, "which", lambda _name: None) assert setup_wizard._install_commands() == [ - [["/tmp/hermes/venv/bin/python", "-m", "pip", "install", "inkbox>=0.4.9", "aiohttp>=3.9", "segno>=1.5"]], + [["/tmp/hermes/venv/bin/python", "-m", "pip", "install", "inkbox>=0.4.10", "aiohttp>=3.9", "segno>=1.5"]], [ ["/tmp/hermes/venv/bin/python", "-m", "ensurepip", "--upgrade"], - ["/tmp/hermes/venv/bin/python", "-m", "pip", "install", "inkbox>=0.4.9", "aiohttp>=3.9", "segno>=1.5"], + ["/tmp/hermes/venv/bin/python", "-m", "pip", "install", "inkbox>=0.4.10", "aiohttp>=3.9", "segno>=1.5"], ], ] @@ -54,7 +54,7 @@ def fail_import(): out = capsys.readouterr().out assert "/tmp/hermes/venv/bin/python" in out assert "uv pip install --python" in out - assert "inkbox>=0.4.9" in out + assert "inkbox>=0.4.10" in out assert "aiohttp>=3.9" in out From 00012f2e9316a8894f13f2f9efbd0efba1b4bb53 Mon Sep 17 00:00:00 2001 From: dimavrem22 Date: Thu, 25 Jun 2026 05:10:34 +0000 Subject: [PATCH 5/9] Require confirming with human and setting up together before Inkbox plugin setup Co-Authored-By: Claude Opus 4.8 (1M context) --- skills/inkbox-plugin-setup/SKILL.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/skills/inkbox-plugin-setup/SKILL.md b/skills/inkbox-plugin-setup/SKILL.md index 830cbd9..a798e30 100644 --- a/skills/inkbox-plugin-setup/SKILL.md +++ b/skills/inkbox-plugin-setup/SKILL.md @@ -6,12 +6,12 @@ user-invocable: false # Inkbox plugin setup -If you self-signed up to Inkbox but the Inkbox plugin isn't configured in your runtime yet, do not set it up on your own — ask the human for permission first. It's the human's decision, not yours. +If you self-signed up to Inkbox but the Inkbox plugin isn't configured in your runtime yet, don't set it up on your own — confirm with your human and do it together before you start. It's a shared decision, not yours alone. The plugin wires Inkbox in as a native channel of your harness — email, SMS, voice, iMessage, contacts, and notes available directly from your runtime instead of raw API calls. ## What to do -1. Ask the human for explicit permission before setting up the Inkbox plugin. +1. Bring it to your human first and get an explicit go-ahead before doing anything. 2. Explain plainly that it gives you native messaging channels in your runtime. -3. Wait for a clear yes. If you don't get one, stop and leave the plugin unconfigured. +3. Set it up together. If you don't get a clear yes, stop and leave the plugin unconfigured. From 3c2386d85256597f5249d996b842e024f2dcf4ce Mon Sep 17 00:00:00 2001 From: dimavrem22 Date: Thu, 25 Jun 2026 05:33:38 +0000 Subject: [PATCH 6/9] Fix inkbox-plugin-setup skill: agent may set up itself after asking permission Co-Authored-By: Claude Opus 4.8 (1M context) --- skills/inkbox-plugin-setup/SKILL.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/skills/inkbox-plugin-setup/SKILL.md b/skills/inkbox-plugin-setup/SKILL.md index a798e30..349f3fd 100644 --- a/skills/inkbox-plugin-setup/SKILL.md +++ b/skills/inkbox-plugin-setup/SKILL.md @@ -6,12 +6,12 @@ user-invocable: false # Inkbox plugin setup -If you self-signed up to Inkbox but the Inkbox plugin isn't configured in your runtime yet, don't set it up on your own — confirm with your human and do it together before you start. It's a shared decision, not yours alone. +If you self-signed up to Inkbox but the Inkbox plugin isn't configured in your runtime yet, ask your human for permission before you start. Once they give the go-ahead, you can set it up yourself. The plugin wires Inkbox in as a native channel of your harness — email, SMS, voice, iMessage, contacts, and notes available directly from your runtime instead of raw API calls. ## What to do -1. Bring it to your human first and get an explicit go-ahead before doing anything. +1. Ask your human for permission first and wait for an explicit go-ahead. 2. Explain plainly that it gives you native messaging channels in your runtime. -3. Set it up together. If you don't get a clear yes, stop and leave the plugin unconfigured. +3. Once they approve, set it up yourself. If you don't get a clear yes, stop and leave the plugin unconfigured. From 14860b0daeaaeebbe6c58b1fd08fec2458c0a5b5 Mon Sep 17 00:00:00 2001 From: dimavrem22 Date: Thu, 25 Jun 2026 18:21:11 +0000 Subject: [PATCH 7/9] chore: drop redundant inkbox-plugin-setup skill The plugin's setup wizard already configures the plugin during signup, so a separate agent-facing "ask permission, then set it up yourself" instruction is redundant. Drop it; keep the harness= signup tagging. Co-Authored-By: Claude Opus 4.8 (1M context) --- skills/inkbox-plugin-setup/SKILL.md | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 skills/inkbox-plugin-setup/SKILL.md diff --git a/skills/inkbox-plugin-setup/SKILL.md b/skills/inkbox-plugin-setup/SKILL.md deleted file mode 100644 index 349f3fd..0000000 --- a/skills/inkbox-plugin-setup/SKILL.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: inkbox-plugin-setup -description: Use when you self-signed up to Inkbox but the Inkbox plugin is not configured in your runtime yet. Setting it up grants native messaging channels, so get the human's permission first. -user-invocable: false ---- - -# Inkbox plugin setup - -If you self-signed up to Inkbox but the Inkbox plugin isn't configured in your runtime yet, ask your human for permission before you start. Once they give the go-ahead, you can set it up yourself. - -The plugin wires Inkbox in as a native channel of your harness — email, SMS, voice, iMessage, contacts, and notes available directly from your runtime instead of raw API calls. - -## What to do - -1. Ask your human for permission first and wait for an explicit go-ahead. -2. Explain plainly that it gives you native messaging channels in your runtime. -3. Once they approve, set it up yourself. If you don't get a clear yes, stop and leave the plugin unconfigured. From e92baafe0cbf904f1b8c260665d0eff18fbe4d6a Mon Sep 17 00:00:00 2001 From: dimavrem22 Date: Thu, 25 Jun 2026 18:23:59 +0000 Subject: [PATCH 8/9] ci: run pytest on PRs Mirror openclaw-plugin's CI. The inkbox SDK is deliberately not installed (tests mock it, and inkbox>=0.4.10 with the harness= kwarg isn't on PyPI yet), so CI installs only the deps the tests actually import. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..2914ea5 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,27 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + # The inkbox SDK is intentionally not installed here: the tests mock it, + # and the pinned inkbox>=0.4.10 (with the harness= signup kwarg) isn't on + # PyPI yet. Install only the deps the tests actually import. + - name: Install test deps + run: pip install pytest aiohttp + + - name: Test + run: pytest -q From 40e8d185314fbcb0e4aafd221493d65ac210bd25 Mon Sep 17 00:00:00 2001 From: dimavrem22 Date: Fri, 26 Jun 2026 20:12:35 +0000 Subject: [PATCH 9/9] chore: trim out-of-place harness/version comments Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci.yml | 4 +--- setup_wizard.py | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2914ea5..a61ebb6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,9 +17,7 @@ jobs: with: python-version: "3.12" - # The inkbox SDK is intentionally not installed here: the tests mock it, - # and the pinned inkbox>=0.4.10 (with the harness= signup kwarg) isn't on - # PyPI yet. Install only the deps the tests actually import. + # inkbox is mocked in the tests, so install only what they import. - name: Install test deps run: pip install pytest aiohttp diff --git a/setup_wizard.py b/setup_wizard.py index 9dba1e1..9c1ebe7 100644 --- a/setup_wizard.py +++ b/setup_wizard.py @@ -309,7 +309,6 @@ def _parse_version(value: str) -> tuple[int, ...]: def _inkbox_version_ok() -> bool: - # Treat an outdated SDK like a missing requirement so the install/upgrade path runs. try: installed = importlib.metadata.version("inkbox") except Exception: @@ -989,7 +988,7 @@ def _self_signup_flow(base_url: str, Inkbox: Any, InkboxAPIError: Any) -> tuple[ note_to_human=note, agent_handle=handle, base_url=base_url, - harness="hermes", # tag which harness drove this signup + harness="hermes", ) break except InkboxAPIError as exc: