Skip to content

feat: Add Notion integration tool + skill - #26

Closed
dogiladeveloper wants to merge 5 commits into
NousResearch:mainfrom
dogiladeveloper:main
Closed

feat: Add Notion integration tool + skill#26
dogiladeveloper wants to merge 5 commits into
NousResearch:mainfrom
dogiladeveloper:main

Conversation

@dogiladeveloper

Copy link
Copy Markdown
Contributor

What this PR adds

Full Notion integration for Hermes Agent — 7 tools covering the complete CRUD lifecycle.

Tools added:

  • notion_search - Search pages/databases
  • notion_get_page - Read full page content
  • notion_create_page - Create new pages
  • notion_append_blocks - Append content
  • notion_update_page - Update properties
  • notion_query_database - Query with filters
  • notion_delete_block - Archive blocks

Setup:

Add NOTION_API_KEY=secret_xxx to ~/.hermes/.env

Files added:

  • tools/notion.py
  • skills/notion/SKILL.md
  • tests/test_notion.py

DEV ROLE submission — Notion integration built with Claude AI assistance, all tests passing ✅

Discord: dogiladeveloper

@teknium1 teknium1 closed this Feb 26, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Already have a skill for notion!

h4x3rotab pushed a commit to Clawdi-AI/hermes-agent that referenced this pull request Apr 10, 2026
…space shell

Cherry-picked from PR NousResearch#26 (clawjasper56). Replaces hardcoded
authenticated=true with useQuery to /api/auth-check endpoint.
Resolved conflict with our isMobile state addition.
h4x3rotab pushed a commit to Clawdi-AI/hermes-agent that referenced this pull request Apr 10, 2026
When the Hermes gateway is running but the HTTP API server is not
enabled, the onboarding screen shows generic advice that doesn't
address the actual problem. Users can have a fully functional gateway
(serving Telegram, Discord, etc.) while the workspace can't connect.

Changes:
- Onboarding connection error now shows step-by-step instructions:
  1. Add API_SERVER_ENABLED=true to ~/.hermes/.env
  2. Restart the gateway
- Updated .env.example to document the requirement
- Added Ollama/LiteLLM/vLLM as explicit alternative backend options

Fixes NousResearch#26
renerocksai added a commit to renerocksai/hermes-agent that referenced this pull request Apr 28, 2026
…agents (phase 10)

The SDK landed PRs NousResearch#24/NousResearch#25/NousResearch#26 in synadia-ai/synadia-agents:
- verb-first subjects (`agents.prompt.{a}.{o}.{s}`, `agents.hb.{a}.{o}.{s}`,
  new `agents.status.{a}.{o}.{s}`) and `metadata.protocol_version="0.3"`
- pinned `_INBOX.agents` reply-inbox prefix (caller-side; no-op for us)
- `name`+`session` collapsed into a single `session_name` (the 5th subject
  token) — `Envelope.session` and the `session=` kwarg on `AgentService` /
  `Agent.prompt` are gone. One service = one session_name.

Package + import root rename: `natsagent` → `synadia-ai-agents`,
`synadia_ai.agents`. Service-side class `Agent` → `AgentService`.

Adapter changes:
- Adopt single-service-per-session: rely on Hermes profile isolation for
  multi-session deployments instead of building an envelope.session demuxer
  on top of `AgentService`. The `_session_locks` dict collapses to a single
  `_session_lock`.
- The SDK explicitly does not own NATS connections: callers build the
  client. Adapter calls `nats.connect(servers=...)` or
  `nats.connect(**sdk.load_context_options(name))` directly.
- Config: `extra.name` + `extra.session_default` → required
  `extra.session_name`; env var `HERMES_NATS_NAME`/`HERMES_NATS_SESSION` →
  `HERMES_NATS_SESSION_NAME`. No migration shim — branch hadn't merged.
- Lock identity rebuilt as `{agent}:{owner}:{session_name}`.

Tests + docs:
- conftest mock renamed `_ensure_natsagent_mock` → `_ensure_synadia_agents_mock`,
  installs under `sys.modules["synadia_ai.agents"]`, also stubs `nats` so
  the adapter's `nats.connect(...)` resolves under test.
- New `mock_nats` fixture in test_nats_connect.py; concurrent-distinct-
  sessions test removed (v0.2-only concept); positive test added that
  chat_id is sourced from `settings.session_name` regardless of any stray
  envelope field.
- design doc §1-§6/§11/§17 updated for v0.3; progress doc gains a Phase 10
  decision-log entry; user-facing nats.md rewritten with verb-first subject
  examples, status endpoint walkthrough, and `_INBOX.agents.>` permission
  note.

Live-verified end-to-end against `nats-server -p 4223` + `hermes-local`
context + `model: anthropic/claude-haiku-4.5` over OpenRouter: real prompt
streamed a real haiku reply through `agents.prompt.hermes.rene.local`,
multi-turn session continuity intact, `/status` slash command dispatched
through the gateway's command registry. Discovery shows
`protocol_version: 0.3`. Heartbeats fire on `agents.hb.hermes.rene.local`.
Status endpoint replies on `agents.status.hermes.rene.local`.

NATS gateway tests: 190/190 green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
renerocksai added a commit to synadia-ai/hermes-agent that referenced this pull request May 6, 2026
…agents (phase 10)

The SDK landed PRs NousResearch#24/NousResearch#25/NousResearch#26 in synadia-ai/synadia-agents:
- verb-first subjects (`agents.prompt.{a}.{o}.{s}`, `agents.hb.{a}.{o}.{s}`,
  new `agents.status.{a}.{o}.{s}`) and `metadata.protocol_version="0.3"`
- pinned `_INBOX.agents` reply-inbox prefix (caller-side; no-op for us)
- `name`+`session` collapsed into a single `session_name` (the 5th subject
  token) — `Envelope.session` and the `session=` kwarg on `AgentService` /
  `Agent.prompt` are gone. One service = one session_name.

Package + import root rename: `natsagent` → `synadia-ai-agents`,
`synadia_ai.agents`. Service-side class `Agent` → `AgentService`.

Adapter changes:
- Adopt single-service-per-session: rely on Hermes profile isolation for
  multi-session deployments instead of building an envelope.session demuxer
  on top of `AgentService`. The `_session_locks` dict collapses to a single
  `_session_lock`.
- The SDK explicitly does not own NATS connections: callers build the
  client. Adapter calls `nats.connect(servers=...)` or
  `nats.connect(**sdk.load_context_options(name))` directly.
- Config: `extra.name` + `extra.session_default` → required
  `extra.session_name`; env var `HERMES_NATS_NAME`/`HERMES_NATS_SESSION` →
  `HERMES_NATS_SESSION_NAME`. No migration shim — branch hadn't merged.
- Lock identity rebuilt as `{agent}:{owner}:{session_name}`.

Tests + docs:
- conftest mock renamed `_ensure_natsagent_mock` → `_ensure_synadia_agents_mock`,
  installs under `sys.modules["synadia_ai.agents"]`, also stubs `nats` so
  the adapter's `nats.connect(...)` resolves under test.
- New `mock_nats` fixture in test_nats_connect.py; concurrent-distinct-
  sessions test removed (v0.2-only concept); positive test added that
  chat_id is sourced from `settings.session_name` regardless of any stray
  envelope field.
- design doc §1-§6/§11/§17 updated for v0.3; progress doc gains a Phase 10
  decision-log entry; user-facing nats.md rewritten with verb-first subject
  examples, status endpoint walkthrough, and `_INBOX.agents.>` permission
  note.

Live-verified end-to-end against `nats-server -p 4223` + `hermes-local`
context + `model: anthropic/claude-haiku-4.5` over OpenRouter: real prompt
streamed a real haiku reply through `agents.prompt.hermes.rene.local`,
multi-turn session continuity intact, `/status` slash command dispatched
through the gateway's command registry. Discovery shows
`protocol_version: 0.3`. Heartbeats fire on `agents.hb.hermes.rene.local`.
Status endpoint replies on `agents.status.hermes.rene.local`.

NATS gateway tests: 190/190 green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ashneil12 referenced this pull request in ashneil12/vanilla-hermes-agent May 18, 2026
)

When the WebUI's model picker sets the active provider to
"venice" (or "crof", "bankr", "cometapi"), the agent's
resolve_provider_client() looked up the slug in
PROVIDER_REGISTRY, failed to find it, and raised:

  "Provider 'venice' is set in config.yaml but no API key
   was found. Set the VENICE_API_KEY environment variable..."

VENICE_API_KEY WAS set in env — the failure was because
the agent had no idea which env var or base URL to use for
"venice" as a slug. PROVIDER_REGISTRY entries for the other
OpenAI-compatible aggregators (Z.AI, MiniMax, Mistral, etc.)
already existed; Venice/CrofAI/Bankr/CometAPI just hadn't
been added in the upstream code.

Adds four api_key-auth entries mirroring the existing
OpenAI-compat ones:
- venice → https://api.venice.ai/api/v1 + VENICE_API_KEY
- crof → https://crof.ai/v1 + CROF_API_KEY
- bankr → https://gateway.bankr.bot/v1 + BANKR_API_KEY
- cometapi → https://api.cometapi.com/v1 + COMETAPI_API_KEY

Companion to the WebUI side (PRs #26/#27/#29/#30/#32/#33)
which made these providers discoverable in the model picker
with their live /v1/models catalogs.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
renerocksai added a commit to synadia-ai/hermes-agent-work that referenced this pull request May 18, 2026
…agents (phase 10)

The SDK landed PRs NousResearch#24/NousResearch#25/NousResearch#26 in synadia-ai/synadia-agents:
- verb-first subjects (`agents.prompt.{a}.{o}.{s}`, `agents.hb.{a}.{o}.{s}`,
  new `agents.status.{a}.{o}.{s}`) and `metadata.protocol_version="0.3"`
- pinned `_INBOX.agents` reply-inbox prefix (caller-side; no-op for us)
- `name`+`session` collapsed into a single `session_name` (the 5th subject
  token) — `Envelope.session` and the `session=` kwarg on `AgentService` /
  `Agent.prompt` are gone. One service = one session_name.

Package + import root rename: `natsagent` → `synadia-ai-agents`,
`synadia_ai.agents`. Service-side class `Agent` → `AgentService`.

Adapter changes:
- Adopt single-service-per-session: rely on Hermes profile isolation for
  multi-session deployments instead of building an envelope.session demuxer
  on top of `AgentService`. The `_session_locks` dict collapses to a single
  `_session_lock`.
- The SDK explicitly does not own NATS connections: callers build the
  client. Adapter calls `nats.connect(servers=...)` or
  `nats.connect(**sdk.load_context_options(name))` directly.
- Config: `extra.name` + `extra.session_default` → required
  `extra.session_name`; env var `HERMES_NATS_NAME`/`HERMES_NATS_SESSION` →
  `HERMES_NATS_SESSION_NAME`. No migration shim — branch hadn't merged.
- Lock identity rebuilt as `{agent}:{owner}:{session_name}`.

Tests + docs:
- conftest mock renamed `_ensure_natsagent_mock` → `_ensure_synadia_agents_mock`,
  installs under `sys.modules["synadia_ai.agents"]`, also stubs `nats` so
  the adapter's `nats.connect(...)` resolves under test.
- New `mock_nats` fixture in test_nats_connect.py; concurrent-distinct-
  sessions test removed (v0.2-only concept); positive test added that
  chat_id is sourced from `settings.session_name` regardless of any stray
  envelope field.
- design doc §1-§6/§11/§17 updated for v0.3; progress doc gains a Phase 10
  decision-log entry; user-facing nats.md rewritten with verb-first subject
  examples, status endpoint walkthrough, and `_INBOX.agents.>` permission
  note.

Live-verified end-to-end against `nats-server -p 4223` + `hermes-local`
context + `model: anthropic/claude-haiku-4.5` over OpenRouter: real prompt
streamed a real haiku reply through `agents.prompt.hermes.rene.local`,
multi-turn session continuity intact, `/status` slash command dispatched
through the gateway's command registry. Discovery shows
`protocol_version: 0.3`. Heartbeats fire on `agents.hb.hermes.rene.local`.
Status endpoint replies on `agents.status.hermes.rene.local`.

NATS gateway tests: 190/190 green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
difeizheng pushed a commit to difeizheng/zdf-hermes-agent that referenced this pull request Jun 3, 2026
Fixes 12 remaining MEDIUM issues from the deep audit (19 total, 7 fixed in Round 12):

design_agent:
- NousResearch#15: add asyncio.wait_for(300s) around LLM API call to prevent infinite hangs
- NousResearch#17: replace 2x hardcoded 'claude-opus-4-8' with shared DEFAULT_MODEL constant

qa_agent / validate_agent:
- NousResearch#20,NousResearch#22,NousResearch#23: already fixed in Round 12 (verified — dynamic timeout/threshold values used)

memory.py:
- NousResearch#24: frontmatter parser uses regex r'^---$' instead of str.split('---',2),
  preventing false splits on content containing '---' (SQL, markdown tables)
- NousResearch#25: parse and preserve 'description' field from frontmatter in metadata,
  fixing write→load roundtrip data loss

profiles.py:
- NousResearch#26: ProfileConfig now frozen=True (immutable dataclass per coding standards)

deploy_agent:
- NousResearch#31: replace 2x sync subprocess.run with asyncio.create_subprocess_exec
- fix 5x .decode() → .decode('utf-8', errors='replace') for Windows CJK safety
- remove unused import subprocess

db.py:
- NousResearch#27: add class docstring explaining RLock + _unlocked pattern
- NousResearch#28: FK constraints already in DDL (verified PRAGMA foreign_keys=ON active)
- NousResearch#29: add _ensure_connection() with PRAGMA integrity_check(1) + auto-reconnect
       on 4 critical methods (create_task, get_task, claim_task, submit_result)
- extract _create_connection() static method for reuse by reconnect

Tests: 79 passed, 0 failed
dizhaky referenced this pull request in dizhaky/hermes-agent Jun 4, 2026
- react-router: 7.14.2 → 7.17.0 (CVE-2026-42342, GHSA-8x6r-g9mw-2r78)
- Fixes Dependabot alert #26
BarnsL added a commit to BarnsL/hermes-agent that referenced this pull request Jul 29, 2026
…Research#27)

The desktop picker listed no Anthropic models at all while the Claude
subscription token was perfectly valid. list_authenticated_providers()
decided whether to emit the provider row from os.environ + auth.json
only, so a backend spawned from a stripped launcher environment saw
none of ANTHROPIC_API_KEY / ANTHROPIC_TOKEN / CLAUDE_CODE_OAUTH_TOKEN
and dropped the row before any model list was built. Claude Code
persists that token as a Windows USER env var (HKCU\Environment), which
a process inherits only if every ancestor of its launch chain did --
hence the intermittent, recurring failure.

Two layers had to change:

- model_switch: new _has_resolvable_provider_token() delegates to
  resolve_anthropic_token(), which already implements the documented
  resolution order (env -> HKCU registry -> credential file -> pool).
  Wired into both credential gates, after the cheap env test so the
  common path stays allocation-free, and defensively imported so a
  broken adapter cannot take down the whole picker.
- auth: is_provider_explicitly_configured() excluded
  CLAUDE_CODE_OAUTH_TOKEN as ambient, which filtered the row back out
  of every explicit_only surface (the chat picker passes
  explicit_only=1) even once the listing gate accepted it. A token
  inherited in the process env is still treated as ambient; one
  persisted under HKCU\Environment is durable user configuration.

Verified live against the running backend on port 54306: before the fix
GET /api/model/options omitted anthropic entirely and ?explicit_only=1
showed a single-model re-auth placeholder row (claude-sonnet-4-6 only),
which is why no other Claude model could be selected. After the fix the
same code path emits all ten models (claude-sonnet-5, claude-fable-5,
claude-opus-4-8, claude-opus-4-7, claude-opus-4-6, claude-sonnet-4-6
and the dated 4.5/4.1 snapshots) in both modes, and still does when the
live catalog fetch fails, so a cold gateway restart keeps a populated
list.

Also documents the CRITICAL NousResearch#26 context clamp at its application site.
The 1M window on these models is real; the 200K default is deliberate
billing protection, because >200K input on a subscription bills the
non-refilling extra-usage lane. The clamp and its anthropic.long_context
escape hatch are unchanged and now pinned by a test in both directions.

Corrects a stale comment referencing a _seed_from_singletons() helper
that does not exist.
ethenotethan added a commit to ethenotethan/harness that referenced this pull request Aug 4, 2026
HermesNative renders ```sankey (researchoors/hermes-native#198) and
```timeline (researchoors/hermes-native#199) blocks natively and
captures id-bearing ones as living artifacts. Both kinds replace
wholesale on merge (no per-kind merge needed), so only the agent
tool's allowlist and schema enum need to know about them — the store
already handles unknown kinds by replacement.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Meraniya pushed a commit to Meraniya/hermes-agent that referenced this pull request Aug 6, 2026
…AN-1385) (NousResearch#26)

baileys 7.0.0-rc.9->rc13 (clears NousResearch#43 critical) + protobufjs 7.6.4 (NousResearch#59,NousResearch#58) in whatsapp-bridge; esbuild+tsx (NousResearch#46,NousResearch#61) in ui-tui; @babel/core (NousResearch#84) in web; joi+http-proxy-middleware (NousResearch#51,NousResearch#89) in website. js-yaml NousResearch#86 accepted (no in-range fix via gray-matter). Bridge startup verified. NousResearch#93/NousResearch#94 (code fixes) separate.

Co-Authored-By: Claude <noreply@anthropic.com>
ethernet8023 added a commit that referenced this pull request Aug 14, 2026
Dep-inventory items #26/#27/#32: three copies of the same
uv - pip - ensurepip strategy grew independently, and lazy_deps'
docstring admitted being a mirror of tools_config's. Copies drift:
the lazy copy had learned that a uv resolver failure must be final
(falling to pip discards exclude-newer and can install a quarantined
release) while the setup-hook copy still fell through, and only one
of them hid console windows on Windows.

installation/pip_ladder.py now owns the mechanics, stdlib-only under
the same run-dont-parse audit as the rest of the package (the ladder
exists precisely for venvs that are missing pip). The policy choices
that used to be baked into each copy are arguments:

* uv_bin - the caller decides what acquiring uv is worth. Setup hooks
  pass ensure_uv() (downloading uv is in scope during setup); lazy
  installs pass resolve_uv() (a download as a side effect of an
  optional import is not).
* uv_resolver_failure_is_final - the lazy policy above. Availability
  failures (binary vanished, could not exec) always fall through:
  uv never evaluated the requirements, so pip is not a second opinion.
* target/constraints - the durable overlay mode sealed installs use.

tools_config._pip_install and lazy_deps._venv_pip_install are now thin
policy wrappers; agent/lsp/install.py already delegated to the former,
so the third copy collapses transitively. A structural test walks both
wrappers' AST (code, not docstrings) and fails if either regrows a
private ladder.

The 5 failing tests in test_lazy_deps.py fail identically without
this change (verified by stash round-trip): pre-existing on the
branch, not introduced here.
ethernet8023 added a commit that referenced this pull request Aug 15, 2026
Dep-inventory items #26/#27/#32: three copies of the same
uv - pip - ensurepip strategy grew independently, and lazy_deps'
docstring admitted being a mirror of tools_config's. Copies drift:
the lazy copy had learned that a uv resolver failure must be final
(falling to pip discards exclude-newer and can install a quarantined
release) while the setup-hook copy still fell through, and only one
of them hid console windows on Windows.

installation/pip_ladder.py now owns the mechanics, stdlib-only under
the same run-dont-parse audit as the rest of the package (the ladder
exists precisely for venvs that are missing pip). The policy choices
that used to be baked into each copy are arguments:

* uv_bin - the caller decides what acquiring uv is worth. Setup hooks
  pass ensure_uv() (downloading uv is in scope during setup); lazy
  installs pass resolve_uv() (a download as a side effect of an
  optional import is not).
* uv_resolver_failure_is_final - the lazy policy above. Availability
  failures (binary vanished, could not exec) always fall through:
  uv never evaluated the requirements, so pip is not a second opinion.
* target/constraints - the durable overlay mode sealed installs use.

tools_config._pip_install and lazy_deps._venv_pip_install are now thin
policy wrappers; agent/lsp/install.py already delegated to the former,
so the third copy collapses transitively. A structural test walks both
wrappers' AST (code, not docstrings) and fails if either regrows a
private ladder.

The 5 failing tests in test_lazy_deps.py fail identically without
this change (verified by stash round-trip): pre-existing on the
branch, not introduced here.
ethernet8023 added a commit that referenced this pull request Aug 19, 2026
Dep-inventory items #26/#27/#32: three copies of the same
uv - pip - ensurepip strategy grew independently, and lazy_deps'
docstring admitted being a mirror of tools_config's. Copies drift:
the lazy copy had learned that a uv resolver failure must be final
(falling to pip discards exclude-newer and can install a quarantined
release) while the setup-hook copy still fell through, and only one
of them hid console windows on Windows.

installation/pip_ladder.py now owns the mechanics, stdlib-only under
the same run-dont-parse audit as the rest of the package (the ladder
exists precisely for venvs that are missing pip). The policy choices
that used to be baked into each copy are arguments:

* uv_bin - the caller decides what acquiring uv is worth. Setup hooks
  pass ensure_uv() (downloading uv is in scope during setup); lazy
  installs pass resolve_uv() (a download as a side effect of an
  optional import is not).
* uv_resolver_failure_is_final - the lazy policy above. Availability
  failures (binary vanished, could not exec) always fall through:
  uv never evaluated the requirements, so pip is not a second opinion.
* target/constraints - the durable overlay mode sealed installs use.

tools_config._pip_install and lazy_deps._venv_pip_install are now thin
policy wrappers; agent/lsp/install.py already delegated to the former,
so the third copy collapses transitively. A structural test walks both
wrappers' AST (code, not docstrings) and fails if either regrows a
private ladder.

The 5 failing tests in test_lazy_deps.py fail identically without
this change (verified by stash round-trip): pre-existing on the
branch, not introduced here.
nicezic pushed a commit to nicezic/hermes-agent that referenced this pull request Aug 26, 2026
…eway-wsl-conflict-issue168

fix(desktop): 处理已存在其它 Hermes Agent 时桌面端无法启动飞书网关 (NousResearch#168)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants