mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-17 09:41:58 +00:00
chore: uptick
This commit is contained in:
parent
420f68e4e2
commit
db884f4646
240 changed files with 25206 additions and 3155 deletions
|
|
@ -12,6 +12,14 @@ import time
|
|||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Set
|
||||
|
||||
try:
|
||||
from hermes_constants import get_hermes_home
|
||||
except ImportError:
|
||||
import os as _os
|
||||
def get_hermes_home() -> Path: # type: ignore[misc]
|
||||
val = (_os.environ.get("HERMES_HOME") or "").strip()
|
||||
return Path(val) if val else Path.home() / ".hermes"
|
||||
|
||||
try:
|
||||
from fastapi import APIRouter
|
||||
except Exception: # Allows local unit tests without dashboard dependencies.
|
||||
|
|
@ -135,15 +143,15 @@ ACHIEVEMENTS: List[Dict[str, Any]] = [
|
|||
|
||||
|
||||
def state_path() -> Path:
|
||||
return Path.home() / ".hermes" / "plugins" / "hermes-achievements" / "state.json"
|
||||
return get_hermes_home() / "plugins" / "hermes-achievements" / "state.json"
|
||||
|
||||
|
||||
def snapshot_path() -> Path:
|
||||
return Path.home() / ".hermes" / "plugins" / "hermes-achievements" / "scan_snapshot.json"
|
||||
return get_hermes_home() / "plugins" / "hermes-achievements" / "scan_snapshot.json"
|
||||
|
||||
|
||||
def checkpoint_path() -> Path:
|
||||
return Path.home() / ".hermes" / "plugins" / "hermes-achievements" / "scan_checkpoint.json"
|
||||
return get_hermes_home() / "plugins" / "hermes-achievements" / "scan_checkpoint.json"
|
||||
|
||||
|
||||
def load_state() -> Dict[str, Any]:
|
||||
|
|
|
|||
42
plugins/kanban/dashboard/dist/index.js
vendored
42
plugins/kanban/dashboard/dist/index.js
vendored
|
|
@ -231,7 +231,7 @@
|
|||
String(this.state.error && this.state.error.message || this.state.error)),
|
||||
h(Button, {
|
||||
onClick: () => this.setState({ error: null }),
|
||||
className: "h-7 px-3 text-xs border border-border hover:bg-foreground/10 cursor-pointer",
|
||||
size: "sm",
|
||||
}, "Reload view"),
|
||||
),
|
||||
);
|
||||
|
|
@ -599,11 +599,11 @@
|
|||
h("div", { className: "flex-1" }),
|
||||
h(Button, {
|
||||
onClick: props.onNudgeDispatch,
|
||||
className: "h-8 px-3 text-xs border border-border hover:bg-foreground/10 cursor-pointer",
|
||||
size: "sm",
|
||||
}, "Nudge dispatcher"),
|
||||
h(Button, {
|
||||
onClick: props.onRefresh,
|
||||
className: "h-8 px-3 text-xs border border-border hover:bg-foreground/10 cursor-pointer",
|
||||
size: "sm",
|
||||
}, "Refresh"),
|
||||
);
|
||||
}
|
||||
|
|
@ -619,21 +619,21 @@
|
|||
`${props.count} selected`),
|
||||
h(Button, {
|
||||
onClick: function () { props.onApply({ status: "ready" }); },
|
||||
className: "hermes-kanban-bulk-btn",
|
||||
size: "sm",
|
||||
}, "→ ready"),
|
||||
h(Button, {
|
||||
onClick: function () {
|
||||
props.onApply({ status: "done" },
|
||||
`Mark ${props.count} task(s) as done?`);
|
||||
},
|
||||
className: "hermes-kanban-bulk-btn",
|
||||
size: "sm",
|
||||
}, "Complete"),
|
||||
h(Button, {
|
||||
onClick: function () {
|
||||
props.onApply({ archive: true },
|
||||
`Archive ${props.count} task(s)?`);
|
||||
},
|
||||
className: "hermes-kanban-bulk-btn",
|
||||
size: "sm",
|
||||
}, "Archive"),
|
||||
h("div", { className: "hermes-kanban-bulk-reassign" },
|
||||
h(Select, {
|
||||
|
|
@ -654,14 +654,13 @@
|
|||
setAssignee("");
|
||||
},
|
||||
disabled: !assignee,
|
||||
className: cn("hermes-kanban-bulk-btn",
|
||||
!assignee ? "opacity-40 cursor-not-allowed" : ""),
|
||||
size: "sm",
|
||||
}, "Apply"),
|
||||
),
|
||||
h("div", { className: "flex-1" }),
|
||||
h(Button, {
|
||||
onClick: props.onClear,
|
||||
className: "hermes-kanban-bulk-btn",
|
||||
size: "sm",
|
||||
}, "Clear"),
|
||||
);
|
||||
}
|
||||
|
|
@ -993,11 +992,11 @@
|
|||
h("div", { className: "flex gap-2" },
|
||||
h(Button, {
|
||||
onClick: submit,
|
||||
className: "h-7 px-2 text-xs border border-border hover:bg-foreground/10 cursor-pointer flex-1",
|
||||
size: "sm",
|
||||
}, "Create"),
|
||||
h(Button, {
|
||||
onClick: props.onCancel,
|
||||
className: "h-7 px-2 text-xs border border-border hover:bg-foreground/10 cursor-pointer",
|
||||
size: "sm",
|
||||
}, "Cancel"),
|
||||
),
|
||||
);
|
||||
|
|
@ -1125,7 +1124,7 @@
|
|||
}),
|
||||
h(Button, {
|
||||
onClick: handleComment,
|
||||
className: "h-8 px-3 text-xs border border-border hover:bg-foreground/10 cursor-pointer",
|
||||
size: "sm",
|
||||
}, "Comment"),
|
||||
) : null,
|
||||
),
|
||||
|
|
@ -1355,10 +1354,10 @@
|
|||
className: "h-8 text-sm flex-1",
|
||||
}),
|
||||
h(Button, { onClick: save,
|
||||
className: "h-7 px-2 text-xs border border-border hover:bg-foreground/10 cursor-pointer",
|
||||
size: "sm",
|
||||
}, "Save"),
|
||||
h(Button, { onClick: props.onCancel,
|
||||
className: "h-7 px-2 text-xs border border-border hover:bg-foreground/10 cursor-pointer",
|
||||
size: "sm",
|
||||
}, "Cancel"),
|
||||
);
|
||||
}
|
||||
|
|
@ -1439,10 +1438,10 @@
|
|||
editing
|
||||
? h("div", { className: "flex gap-1" },
|
||||
h(Button, { onClick: save,
|
||||
className: "h-6 px-2 text-xs border border-border hover:bg-foreground/10 cursor-pointer",
|
||||
size: "sm",
|
||||
}, "Save"),
|
||||
h(Button, { onClick: function () { setEditing(false); setV(props.task.body || ""); },
|
||||
className: "h-6 px-2 text-xs border border-border hover:bg-foreground/10 cursor-pointer",
|
||||
size: "sm",
|
||||
}, "Cancel"),
|
||||
)
|
||||
: h("button", {
|
||||
|
|
@ -1516,8 +1515,7 @@
|
|||
props.onAddParent(newParent).then(function () { setNewParent(""); });
|
||||
},
|
||||
disabled: !newParent,
|
||||
className: cn("h-7 px-2 text-xs border border-border cursor-pointer",
|
||||
!newParent ? "opacity-40 cursor-not-allowed" : "hover:bg-foreground/10"),
|
||||
size: "sm",
|
||||
}, "+ parent"),
|
||||
),
|
||||
h("div", { className: "hermes-kanban-deps-row" },
|
||||
|
|
@ -1556,8 +1554,7 @@
|
|||
props.onAddChild(newChild).then(function () { setNewChild(""); });
|
||||
},
|
||||
disabled: !newChild,
|
||||
className: cn("h-7 px-2 text-xs border border-border cursor-pointer",
|
||||
!newChild ? "opacity-40 cursor-not-allowed" : "hover:bg-foreground/10"),
|
||||
size: "sm",
|
||||
}, "+ child"),
|
||||
),
|
||||
);
|
||||
|
|
@ -1569,10 +1566,7 @@
|
|||
return h(Button, {
|
||||
onClick: function () { if (enabled !== false) props.onPatch(patch, { confirm: confirmMsg }); },
|
||||
disabled: enabled === false,
|
||||
className: cn(
|
||||
"h-7 px-2 text-xs border border-border cursor-pointer",
|
||||
enabled === false ? "opacity-40 cursor-not-allowed" : "hover:bg-foreground/10",
|
||||
),
|
||||
size: "sm",
|
||||
}, label);
|
||||
};
|
||||
return h("div", { className: "hermes-kanban-actions" },
|
||||
|
|
|
|||
12
plugins/kanban/dashboard/dist/style.css
vendored
12
plugins/kanban/dashboard/dist/style.css
vendored
|
|
@ -251,6 +251,11 @@
|
|||
border-radius: var(--radius-sm, 0.25rem);
|
||||
}
|
||||
|
||||
.hermes-kanban-inline-create > .flex.gap-2:last-child > button:first-of-type {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
/* ---- Drawer (task detail side panel) --------------------------------- */
|
||||
|
||||
.hermes-kanban-drawer-shade {
|
||||
|
|
@ -460,14 +465,17 @@
|
|||
font-size: 0.75rem;
|
||||
padding-right: 0.25rem;
|
||||
}
|
||||
.hermes-kanban-bulk-btn {
|
||||
|
||||
.hermes-kanban-bulk > button,
|
||||
.hermes-kanban-bulk-reassign > button {
|
||||
height: 1.7rem !important;
|
||||
padding: 0 0.5rem !important;
|
||||
font-size: 0.7rem !important;
|
||||
border: 1px solid var(--color-border);
|
||||
cursor: pointer;
|
||||
}
|
||||
.hermes-kanban-bulk-btn:hover {
|
||||
.hermes-kanban-bulk > button:hover:not(:disabled),
|
||||
.hermes-kanban-bulk-reassign > button:hover:not(:disabled) {
|
||||
background: color-mix(in srgb, var(--color-foreground) 8%, transparent);
|
||||
}
|
||||
.hermes-kanban-bulk-reassign {
|
||||
|
|
|
|||
|
|
@ -110,6 +110,17 @@ def _parse_context_tokens(host_val, root_val) -> int | None:
|
|||
return None
|
||||
|
||||
|
||||
def _parse_int_config(host_val, root_val, default: int) -> int:
|
||||
"""Parse an integer config: host wins, then root, then default."""
|
||||
for val in (host_val, root_val):
|
||||
if val is not None:
|
||||
try:
|
||||
return int(val)
|
||||
except (ValueError, TypeError):
|
||||
pass
|
||||
return default
|
||||
|
||||
|
||||
def _parse_dialectic_depth(host_val, root_val) -> int:
|
||||
"""Parse dialecticDepth: host wins, then root, then 1. Clamped to 1-3."""
|
||||
for val in (host_val, root_val):
|
||||
|
|
@ -463,10 +474,10 @@ class HonchoClientConfig:
|
|||
raw.get("dialecticDynamic"),
|
||||
default=True,
|
||||
),
|
||||
dialectic_max_chars=int(
|
||||
host_block.get("dialecticMaxChars")
|
||||
or raw.get("dialecticMaxChars")
|
||||
or 600
|
||||
dialectic_max_chars=_parse_int_config(
|
||||
host_block.get("dialecticMaxChars"),
|
||||
raw.get("dialecticMaxChars"),
|
||||
default=600,
|
||||
),
|
||||
dialectic_depth=_parse_dialectic_depth(
|
||||
host_block.get("dialecticDepth"),
|
||||
|
|
@ -487,15 +498,15 @@ class HonchoClientConfig:
|
|||
or raw.get("reasoningLevelCap")
|
||||
or "high"
|
||||
),
|
||||
message_max_chars=int(
|
||||
host_block.get("messageMaxChars")
|
||||
or raw.get("messageMaxChars")
|
||||
or 25000
|
||||
message_max_chars=_parse_int_config(
|
||||
host_block.get("messageMaxChars"),
|
||||
raw.get("messageMaxChars"),
|
||||
default=25000,
|
||||
),
|
||||
dialectic_max_input_chars=int(
|
||||
host_block.get("dialecticMaxInputChars")
|
||||
or raw.get("dialecticMaxInputChars")
|
||||
or 10000
|
||||
dialectic_max_input_chars=_parse_int_config(
|
||||
host_block.get("dialecticMaxInputChars"),
|
||||
raw.get("dialecticMaxInputChars"),
|
||||
default=10000,
|
||||
),
|
||||
recall_mode=_normalize_recall_mode(
|
||||
host_block.get("recallMode")
|
||||
|
|
|
|||
|
|
@ -160,11 +160,13 @@ class HonchoSessionManager:
|
|||
Peers are lazy -- no API call until first use.
|
||||
Observation settings are controlled per-session via SessionPeerConfig.
|
||||
"""
|
||||
if peer_id in self._peers_cache:
|
||||
return self._peers_cache[peer_id]
|
||||
with self._cache_lock:
|
||||
if peer_id in self._peers_cache:
|
||||
return self._peers_cache[peer_id]
|
||||
|
||||
peer = self.honcho.peer(peer_id)
|
||||
self._peers_cache[peer_id] = peer
|
||||
with self._cache_lock:
|
||||
self._peers_cache[peer_id] = peer
|
||||
return peer
|
||||
|
||||
def _get_or_create_honcho_session(
|
||||
|
|
@ -176,9 +178,10 @@ class HonchoSessionManager:
|
|||
Returns:
|
||||
Tuple of (honcho_session, existing_messages).
|
||||
"""
|
||||
if session_id in self._sessions_cache:
|
||||
logger.debug("Honcho session '%s' retrieved from cache", session_id)
|
||||
return self._sessions_cache[session_id], []
|
||||
with self._cache_lock:
|
||||
if session_id in self._sessions_cache:
|
||||
logger.debug("Honcho session '%s' retrieved from cache", session_id)
|
||||
return self._sessions_cache[session_id], []
|
||||
|
||||
session = self.honcho.session(session_id)
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ except ImportError:
|
|||
|
||||
try:
|
||||
from microsoft_teams.apps import App, ActivityContext
|
||||
from microsoft_teams.common.http.client import ClientOptions
|
||||
from microsoft_teams.api import MessageActivity, ConversationReference
|
||||
from microsoft_teams.api.activities.typing import TypingActivityInput
|
||||
from microsoft_teams.api.activities.invoke.adaptive_card import AdaptiveCardInvokeActivity
|
||||
|
|
@ -57,6 +58,7 @@ try:
|
|||
TEAMS_SDK_AVAILABLE = True
|
||||
except ImportError:
|
||||
TEAMS_SDK_AVAILABLE = False
|
||||
ClientOptions = None # type: ignore[assignment,misc]
|
||||
App = None # type: ignore[assignment,misc]
|
||||
ActivityContext = None # type: ignore[assignment,misc]
|
||||
MessageActivity = None # type: ignore[assignment,misc]
|
||||
|
|
@ -208,6 +210,7 @@ class TeamsAdapter(BasePlatformAdapter):
|
|||
client_secret=self._client_secret,
|
||||
tenant_id=self._tenant_id,
|
||||
http_server_adapter=_AiohttpBridgeAdapter(aiohttp_app),
|
||||
client=ClientOptions(headers={"User-Agent": "Hermes"}),
|
||||
)
|
||||
|
||||
# Register message handler before initialize()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue