Merge branch 'main' of github.com:NousResearch/hermes-agent into bb/gui

# Conflicts:
#	cli.py
#	hermes_cli/main.py
#	run_agent.py
#	tests/hermes_cli/test_cmd_update.py
#	tools/mcp_tool.py
#	web/src/lib/gatewayClient.ts
This commit is contained in:
Brooklyn Nicholson
2026-05-18 01:26:56 -05:00
260 changed files with 24547 additions and 13573 deletions
@@ -30,6 +30,7 @@ import { Card } from "@/components/ui/card";
import { ModelPickerDialog } from "@/components/ModelPickerDialog";
import { ToolCall, type ToolEntry } from "@/components/ToolCall";
import { GatewayClient, type ConnectionState } from "@/lib/gatewayClient";
import { HERMES_BASE_PATH } from "@/lib/api";
import { cn } from "@/lib/utils";
import { AlertCircle, ChevronDown, RefreshCw } from "lucide-react";
@@ -160,7 +161,7 @@ export function ChatSidebar({ channel, className }: ChatSidebarProps) {
const proto = window.location.protocol === "https:" ? "wss:" : "ws:";
const qs = new URLSearchParams({ token, channel });
const ws = new WebSocket(
`${proto}//${window.location.host}/api/events?${qs.toString()}`,
`${proto}//${window.location.host}${HERMES_BASE_PATH}/api/events?${qs.toString()}`,
);
// `unmounting` suppresses the banner during cleanup — `ws.close()`
+3 -1
View File
@@ -5,6 +5,8 @@ import {
type GatewayEventName,
} from "@hermes/shared";
import { HERMES_BASE_PATH } from "@/lib/api";
export type { ConnectionState, GatewayEvent, GatewayEventName };
/**
@@ -24,7 +26,7 @@ export class GatewayClient extends JsonRpcGatewayClient {
const scheme = location.protocol === "https:" ? "wss:" : "ws:";
await super.connect(
`${scheme}//${location.host}/api/ws?token=${encodeURIComponent(resolved)}`,
`${scheme}//${location.host}${HERMES_BASE_PATH}/api/ws?token=${encodeURIComponent(resolved)}`,
);
}
}
+13 -1
View File
@@ -24,6 +24,7 @@ import { Terminal } from "@xterm/xterm";
import "@xterm/xterm/css/xterm.css";
import { Button } from "@nous-research/ui/ui/components/button";
import { Typography } from "@/components/NouiTypography";
import { HERMES_BASE_PATH } from "@/lib/api";
import { cn } from "@/lib/utils";
import { Copy, PanelRight, X } from "lucide-react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
@@ -44,7 +45,7 @@ function buildWsUrl(
const proto = window.location.protocol === "https:" ? "wss:" : "ws:";
const qs = new URLSearchParams({ token, channel });
if (resume) qs.set("resume", resume);
return `${proto}//${window.location.host}/api/pty?${qs.toString()}`;
return `${proto}//${window.location.host}${HERMES_BASE_PATH}/api/pty?${qs.toString()}`;
}
// Channel id ties this chat tab's PTY child (publisher) to its sidebar
@@ -286,6 +287,17 @@ export default function ChatPage({ isActive = true }: { isActive?: boolean }) {
fontWeight: "400",
fontWeightBold: "700",
macOptionIsMeta: true,
// Hold Option (Alt on Linux/Windows) to force native text selection
// even when the inner Hermes TUI has enabled xterm mouse-events
// mode (CSI ?1000h family). Without this, click-and-drag in the
// chat canvas selects nothing and Cmd+C falls back to copying the
// entire visible buffer, which is rarely what the user wants.
// See #25720.
macOptionClickForcesSelection: true,
// Right-click selects the word under the pointer. xterm.js default
// is false; enabling it gives users a single-action selection
// path on top of the modifier-based bypass above.
rightClickSelectsWord: true,
// Single-scroll-system experiment:
// let the inner Hermes TUI own transcript history/scroll behavior.
// The outer browser xterm should act as a display/input bridge only.