mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-11-15 18:35:29 +03:00
d0b49116ec
A third-party client can now say who it is: session.create takes an optional
client {name, version?}. It is attribution only. source still picks the
policy, and no toolset, approval, permission, prompt text or telemetry reads
the label.
- Validated beside the editor check (bounded, safe charset); a malformed value
is invalid_params on field client.
- Kept inside the frozen creation request, so there is no new column, receipt
key or policy field: an older owner restores the session, and the label is
part of the exact-retry identity.
- session.info.client echoes it (absent when none was sent); runtime.describe
lists client in session_create.parameters and capability session-client-v1.
- Plugins read it with hermes_cli.plugin_session.session_client() (published
in plugin_api.json) and the client / client_version keys of prompt-section
session info ("" when none). No PluginContext method, no hook kwarg.
- The classic CLI's /new copies the frozen launch request but never the
creating client's label: the new session belongs to the terminal.
- Contracts regenerated; docs say the label is self-declared and must never
grant anything.
62 lines
2.8 KiB
Python
62 lines
2.8 KiB
Python
"""The session a plugin hook or tool is running for, read from the turn's task-local context.
|
|
|
|
Plugin hooks and tools run in the gateway process, whose own cwd is the install root and is shared
|
|
by every session (it is never ``os.chdir``-ed). These read the calling session's key, client surface
|
|
and recorded working directory instead.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
|
|
|
|
def _active_policy():
|
|
from gateway.session_policy import active_policy
|
|
return active_policy()
|
|
|
|
|
|
def session_key() -> str:
|
|
"""Route key of the session whose turn is running in this context, ``""`` outside one."""
|
|
from gateway.session_context import get_session_env
|
|
return get_session_env("HERMES_SESSION_KEY", "")
|
|
|
|
|
|
def session_surface() -> str:
|
|
"""``cli``/``tui``/``desktop``/``acp`` for a local session's turn, the messaging platform
|
|
(``telegram``, ``discord``, ...) for a chat's turn, ``""`` outside any session."""
|
|
policy = _active_policy()
|
|
if policy is not None:
|
|
return policy.platform
|
|
from gateway.session_context import get_session_env
|
|
return get_session_env("HERMES_SESSION_PLATFORM", "")
|
|
|
|
|
|
def session_client() -> dict | None:
|
|
"""The client that created the calling local session, as it declared itself on ``session.create``:
|
|
a copy of ``{"name": ..., "version": ...}`` (``version`` only when sent). ``None`` outside a local
|
|
session, for a messaging chat, and for a client that sent no ``client`` (Ink, Desktop, the CLI and
|
|
ACP today). A label the client chose, not an authentication: never grant anything on it.
|
|
Under ``plugins.isolation: host`` the plugin's own process has no session context; read
|
|
``info["client"]`` in a prompt section there."""
|
|
from gateway.session_client import policy_client
|
|
return policy_client(_active_policy())
|
|
|
|
|
|
def session_cwd() -> str:
|
|
"""The calling session's recorded working directory (a local session's workspace, else the
|
|
profile's terminal cwd), ``""`` when it has none. Never the gateway process's own cwd.
|
|
In ingress hooks (``pre_gateway_dispatch``), which run before any session, it is the profile's
|
|
terminal cwd, not the workspace of the session the message will reach."""
|
|
from agent.runtime_cwd import scope_terminal_cwd, scoped_session_cwd
|
|
policy = _active_policy()
|
|
return scoped_session_cwd() or (policy.cwd if policy is not None else "") or scope_terminal_cwd().strip()
|
|
|
|
|
|
def context_surface(manager) -> str:
|
|
"""``session_surface()`` for a plugin context: the classic CLI process itself is ``cli``."""
|
|
return "cli" if manager._cli_ref is not None else session_surface()
|
|
|
|
|
|
def context_cwd(manager) -> str:
|
|
"""``session_cwd()`` for a plugin context: the classic CLI process keeps its launch directory."""
|
|
return os.getcwd() if manager._cli_ref is not None else session_cwd()
|