Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions docs/HARNESSES.md
Original file line number Diff line number Diff line change
Expand Up @@ -677,9 +677,13 @@ Hermes lifecycle.

| Tool | Description |
|------|-------------|
| `signet_search` | Hybrid memory search (keyword + semantic + knowledge graph) |
| `signet_store` | Store a fact/preference/decision with auto entity extraction |
| `signet_profile` | Broad overview of stored memories and working context |
| `memory_search` | Hybrid memory search (keyword + semantic + knowledge graph) |
| `memory_store` | Store a fact/preference/decision with auto entity extraction |
| `memory_get` | Retrieve a memory by ID |
| `memory_list` | List memories with optional filters |
| `memory_modify` | Edit an existing memory |
| `memory_forget` | Soft-delete a memory |
| `recall` / `remember` | Compatibility aliases for search/store |

### Supported hooks

Expand Down
5 changes: 4 additions & 1 deletion packages/cli/src/commands/memory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ describe("registerMemoryCommands recall", () => {
};

let capturedBody: unknown;
let capturedTimeout: number | undefined;
const program = new Command();
registerMemoryCommands(program, {
ensureDaemonForSecrets: async () => true,
secretApiCall: async (_method, _path, body) => {
secretApiCall: async (_method, _path, body, timeoutMs) => {
capturedBody = body;
capturedTimeout = timeoutMs;
return {
ok: true,
data: {
Expand Down Expand Up @@ -113,6 +115,7 @@ describe("registerMemoryCommands recall", () => {
until: "2026-04-01",
expand: true,
});
expect(capturedTimeout).toBe(30_000);
expect(lines).toHaveLength(1);
expect(lines[0]).toContain('"high score row"');
expect(lines[0]).not.toContain('"low score row"');
Expand Down
37 changes: 22 additions & 15 deletions packages/cli/src/commands/memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import chalk from "chalk";
import type { Command } from "commander";
import ora from "ora";

const MEMORY_RECALL_TIMEOUT_MS = 30_000;

interface MemoryDeps {
readonly ensureDaemonForSecrets: () => Promise<boolean>;
readonly secretApiCall: (
Expand Down Expand Up @@ -164,21 +166,26 @@ export function registerMemoryCommands(program: Command, deps: MemoryDeps): void
if (!(await deps.ensureDaemonForSecrets())) return;

const spinner = ora("Searching memories...").start();
const { ok, data } = await deps.secretApiCall("POST", "/api/memory/recall", {
query,
keywordQuery: options.keywordQuery,
limit: options.limit,
project: options.project,
type: options.type,
tags: options.tags,
who: options.who,
pinned: options.pinned === true ? true : undefined,
importance_min: options.importanceMin,
since: options.since,
until: options.until,
expand: options.expand === true ? true : undefined,
...(options.agent ? { agentId: options.agent } : {}),
});
const { ok, data } = await deps.secretApiCall(
"POST",
"/api/memory/recall",
{
query,
keywordQuery: options.keywordQuery,
limit: options.limit,
project: options.project,
type: options.type,
tags: options.tags,
who: options.who,
pinned: options.pinned === true ? true : undefined,
importance_min: options.importanceMin,
since: options.since,
until: options.until,
expand: options.expand === true ? true : undefined,
...(options.agent ? { agentId: options.agent } : {}),
},
MEMORY_RECALL_TIMEOUT_MS,
);

const err = typeof data === "object" && data !== null && "error" in data ? data.error : undefined;
if (!ok || typeof err === "string") {
Expand Down
15 changes: 10 additions & 5 deletions packages/connector-hermes-agent/hermes-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,20 @@ signet start # ensure daemon is running
Environment variables:
- `SIGNET_DAEMON_URL` — Full daemon URL (default: `http://localhost:3850`)
- `SIGNET_HOST` / `SIGNET_PORT` — Host and port separately
- `SIGNET_AGENT_ID` — Agent scope identifier (default: `default`)
- `SIGNET_AGENT_ID` — Agent scope identifier (default: `hermes-agent`)
- `SIGNET_AGENT_WORKSPACE` — Optional named-agent workspace path (for example `~/.agents/agents/dot`)

## Tools

| Tool | Description |
|------|-------------|
| `signet_search` | Hybrid memory search (keyword + semantic + knowledge graph) |
| `signet_store` | Store a fact, preference, or decision to memory |
| `signet_profile` | Broad overview of stored memories and context |
| `memory_search` | Hybrid memory search (keyword + semantic + knowledge graph) |
| `memory_store` | Store a fact, preference, or decision to memory |
| `memory_get` | Retrieve a memory by ID |
| `memory_list` | List memories with optional filters |
| `memory_modify` | Edit an existing memory |
| `memory_forget` | Soft-delete a memory |
| `recall` / `remember` | Compatibility aliases for search/store |

## How It Works

Expand All @@ -44,4 +49,4 @@ The plugin bridges Hermes Agent's memory lifecycle to the Signet daemon:

3. **Session end** — Sends the conversation transcript to Signet's session-end hook, which queues it for the memory pipeline: extraction, knowledge graph updates, retention decay, and MEMORY.md synthesis.

4. **Explicit tools** — The agent can call `signet_search`, `signet_store`, and `signet_profile` directly during conversation for on-demand memory operations.
4. **Explicit tools** — The agent can call canonical Signet tools such as `memory_search` and `memory_store` directly during conversation for on-demand memory operations. Legacy `signet_*` names are handled for compatibility but are not advertised to the model.
Loading
Loading