@signetai/connector-hermes-agent 0.193.0 → 0.193.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +389 -13
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -6918,6 +6918,99 @@ var PIPELINE_PROVIDER_CHOICES = [
|
|
|
6918
6918
|
var SYNTHESIS_PROVIDER_CHOICES = PIPELINE_PROVIDER_CHOICES.filter((provider) => provider !== "command");
|
|
6919
6919
|
var PIPELINE_PROVIDER_SET = new Set(PIPELINE_PROVIDER_CHOICES);
|
|
6920
6920
|
var SYNTHESIS_PROVIDER_SET = new Set(SYNTHESIS_PROVIDER_CHOICES);
|
|
6921
|
+
var MEMORY_CONTENT_SAFETY_POLICY_VERSION = "memory-content-safety-v1";
|
|
6922
|
+
var MEMORY_CONTENT_SAFETY_REASONS = [
|
|
6923
|
+
"prompt_injection",
|
|
6924
|
+
"exfiltration",
|
|
6925
|
+
"credential_harvesting",
|
|
6926
|
+
"malicious_shell",
|
|
6927
|
+
"tool_directive",
|
|
6928
|
+
"invisible_unicode"
|
|
6929
|
+
];
|
|
6930
|
+
var INVISIBLE_UNICODE_RE = /(?:\u034f|[\u00ad\u061c\u070f\u180e\u200b\u200c\u200e\u200f\u202a-\u202e\u2060\u2066-\u2069\u206a-\u206f\ufeff]|[\u{e0000}-\u{e007f}])/u;
|
|
6931
|
+
var STRONG_DEFENSIVE_CONTEXT_RE = /\b(?:security\s+(?:guidance|discussion|analysis)|threat\s+model|defensive)\b/i;
|
|
6932
|
+
var REPORTING_CONTEXT_RE = /\b(?:example|illustrat\w*|sample|quote|quoted|detector|scanner|classif\w*)\b/i;
|
|
6933
|
+
var REPORTING_BEFORE_RE = /\b(?:example|illustrat\w*|sample|quote|quoted|detector|scanner|classif\w*)\b[\s\S]{0,80}\b(?:say\w*|read\w*|show\w*|flag\w*|detect\w*|describ\w*|demonstrat\w*|contain\w*|match\w*|pattern)\b/i;
|
|
6934
|
+
var REPORTING_AFTER_RE = /\b(?:detector|scanner|classif\w*|flag\w*|pattern|dangerous|unsafe|malicious|hostile|should|would|must|never|do not|don't|avoid|quoted)\b/i;
|
|
6935
|
+
var NEGATED_DIRECTIVE_RE = /\b(?:never|do not|don't|should not|must not|cannot|can't|avoid|prevent|detect|mitigat\w*)\b[\s\S]{0,80}$/i;
|
|
6936
|
+
var PROMPT_INJECTION_RES = [
|
|
6937
|
+
/\b(?:ignore|disregard|override|forget|bypass)\b[\s\S]{0,100}\b(?:previous|prior|above|earlier|system|developer|assistant|safety|security)?\s*(?:instructions?|rules?|prompt|message)\b/i,
|
|
6938
|
+
/\b(?:new|following|these)\s+(?:(?:system|developer|assistant|hidden)\s+)?instructions?\b/i,
|
|
6939
|
+
/(?:^|\n)\s*(?:system|developer|instruction|prompt)\s*:/im,
|
|
6940
|
+
/<\s*(?:system|developer|assistant|instruction|prompt)\b[^>]*>/i,
|
|
6941
|
+
/\b(?:you are now|act as|roleplay as|pretend to be)\b[\s\S]{0,80}\b(?:system|admin|developer|unrestricted|jailbreak|different agent)\b/i
|
|
6942
|
+
];
|
|
6943
|
+
var TOOL_DIRECTIVE_RES = [
|
|
6944
|
+
/<\s*(?:tool[_-]?call|function[_-]?call|invoke|tool)\b/i,
|
|
6945
|
+
/\b(?:assistant|system)\s+to\s*=\s*[a-z0-9_.-]+/i,
|
|
6946
|
+
/\b(?:call|invoke|use|run|execute)\s+(?:the\s+)?[a-z0-9_.-]+\s+tool\b/i
|
|
6947
|
+
];
|
|
6948
|
+
var EXFILTRATION_RE = /\b(?:reveal|show|print|send|upload|exfiltrat\w*|dump|forward|leak|transmit|export)\b[\s\S]{0,120}(?:\b(?:system\s+prompt|hidden\s+instructions?|secret(?:s)?|credential(?:s)?|password(?:s)?|api\s*keys?|tokens?|private\s+keys?|environment\s+variables?)\b|\.env\b|~\/(?:\.ssh)\/\S+|\/etc\/(?:shadow|passwd)\b)/i;
|
|
6949
|
+
var EXFILTRATION_REVERSE = /(?:\b(?:system\s+prompt|hidden\s+instructions?|secret(?:s)?|credential(?:s)?|password(?:s)?|api\s*keys?|tokens?|private\s+keys?|environment\s+variables?)\b|\.env\b|~\/(?:\.ssh)\/\S+|\/etc\/(?:shadow|passwd)\b)[\s\S]{0,120}\b(?:reveal|show|print|send|upload|exfiltrat\w*|dump|forward|leak|transmit|export)\b/i;
|
|
6950
|
+
var CREDENTIAL_HARVESTING_RE = /\b(?:enter|paste|provide|share|send|give|submit|type|hand over)\b[\s\S]{0,80}\b(?:password|api\s*key|token|secret|credential|private\s+key)\b/i;
|
|
6951
|
+
var DANGEROUS_SHELL_RE = /\b(?:curl|wget)\b[^\n]{0,240}\|\s*(?:ba|z|fi)?sh\b|\brm\s+-rf\s+(?:\/|~|\.ssh)[^\n]{0,240}|\b(?:cat|head|tail)\s+~\/?\.ssh\/(?:id_[a-z]+|authorized_keys)\b|\b(?:printenv|env)\b[^\n]{0,120}\b(?:curl|wget|send|upload|post)\b/i;
|
|
6952
|
+
function matchHasDefensiveContext(content, match) {
|
|
6953
|
+
if (!match || !match[0])
|
|
6954
|
+
return false;
|
|
6955
|
+
const start = match.index ?? 0;
|
|
6956
|
+
const before = content.slice(Math.max(0, start - 120), start);
|
|
6957
|
+
const after = content.slice(start + match[0].length, start + match[0].length + 160);
|
|
6958
|
+
return STRONG_DEFENSIVE_CONTEXT_RE.test(match[0]) || NEGATED_DIRECTIVE_RE.test(before) || STRONG_DEFENSIVE_CONTEXT_RE.test(before) || STRONG_DEFENSIVE_CONTEXT_RE.test(after) || REPORTING_BEFORE_RE.test(before) || REPORTING_CONTEXT_RE.test(before) && REPORTING_AFTER_RE.test(after);
|
|
6959
|
+
}
|
|
6960
|
+
function hasActionableMatch(content, patterns) {
|
|
6961
|
+
return patterns.some((pattern) => {
|
|
6962
|
+
const flags = pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`;
|
|
6963
|
+
const searchable = new RegExp(pattern.source, flags);
|
|
6964
|
+
let match;
|
|
6965
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
6966
|
+
if (!matchHasDefensiveContext(content, match))
|
|
6967
|
+
return true;
|
|
6968
|
+
if (match[0].length === 0)
|
|
6969
|
+
searchable.lastIndex += 1;
|
|
6970
|
+
}
|
|
6971
|
+
return false;
|
|
6972
|
+
});
|
|
6973
|
+
}
|
|
6974
|
+
function hasDangerousShell(content) {
|
|
6975
|
+
const searchable = new RegExp(DANGEROUS_SHELL_RE.source, `${DANGEROUS_SHELL_RE.flags}g`);
|
|
6976
|
+
let match;
|
|
6977
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
6978
|
+
if (matchHasDefensiveContext(content, match))
|
|
6979
|
+
continue;
|
|
6980
|
+
const end = (match.index ?? 0) + match[0].length;
|
|
6981
|
+
const after = content.slice(end, end + 160);
|
|
6982
|
+
if (!STRONG_DEFENSIVE_CONTEXT_RE.test(after) && !REPORTING_AFTER_RE.test(after))
|
|
6983
|
+
return true;
|
|
6984
|
+
if (match[0].length === 0)
|
|
6985
|
+
searchable.lastIndex += 1;
|
|
6986
|
+
}
|
|
6987
|
+
return false;
|
|
6988
|
+
}
|
|
6989
|
+
function scanMemoryContent(content) {
|
|
6990
|
+
const raw = typeof content === "string" ? content : String(content ?? "");
|
|
6991
|
+
const normalized = raw.normalize("NFKC");
|
|
6992
|
+
const reasons = new Set;
|
|
6993
|
+
if (INVISIBLE_UNICODE_RE.test(raw))
|
|
6994
|
+
reasons.add("invisible_unicode");
|
|
6995
|
+
if (hasActionableMatch(normalized, PROMPT_INJECTION_RES))
|
|
6996
|
+
reasons.add("prompt_injection");
|
|
6997
|
+
if (hasActionableMatch(normalized, TOOL_DIRECTIVE_RES))
|
|
6998
|
+
reasons.add("tool_directive");
|
|
6999
|
+
if (hasActionableMatch(normalized, [EXFILTRATION_RE, EXFILTRATION_REVERSE]))
|
|
7000
|
+
reasons.add("exfiltration");
|
|
7001
|
+
if (hasActionableMatch(normalized, [CREDENTIAL_HARVESTING_RE]))
|
|
7002
|
+
reasons.add("credential_harvesting");
|
|
7003
|
+
if (hasDangerousShell(normalized))
|
|
7004
|
+
reasons.add("malicious_shell");
|
|
7005
|
+
const orderedReasons = MEMORY_CONTENT_SAFETY_REASONS.filter((reason) => reasons.has(reason));
|
|
7006
|
+
const status = orderedReasons.length === 0 ? "clean" : orderedReasons.every((reason) => reason === "invisible_unicode") ? "tainted" : "blocked";
|
|
7007
|
+
return {
|
|
7008
|
+
status,
|
|
7009
|
+
contextEligible: status === "clean",
|
|
7010
|
+
reasons: orderedReasons,
|
|
7011
|
+
policyVersion: MEMORY_CONTENT_SAFETY_POLICY_VERSION
|
|
7012
|
+
};
|
|
7013
|
+
}
|
|
6921
7014
|
var DAEMON_DERIVED_MEMORY_SOURCE_TYPES = ["extract", "aggregate-recall", "session_end", "checkpoint", "dreaming"];
|
|
6922
7015
|
var MEMORIES_FTS_TOKENIZER = "unicode61";
|
|
6923
7016
|
function normalizeSql(sql) {
|
|
@@ -10896,6 +10989,95 @@ function up124(db) {
|
|
|
10896
10989
|
ON imported_source_lifecycle(agent_id, status, updated_at DESC);
|
|
10897
10990
|
`);
|
|
10898
10991
|
}
|
|
10992
|
+
function tableExists2(db, table) {
|
|
10993
|
+
return db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
10994
|
+
}
|
|
10995
|
+
function hasColumn24(db, table, column) {
|
|
10996
|
+
return db.prepare(`PRAGMA table_info("${table}")`).all().some((row) => row.name === column);
|
|
10997
|
+
}
|
|
10998
|
+
function backfill(db, rows, sourceKind, scannedAt) {
|
|
10999
|
+
const statement = db.prepare(`INSERT INTO memory_content_safety
|
|
11000
|
+
(agent_id, source_kind, source_id, status, context_eligible, reasons_json, policy_version, scanned_at)
|
|
11001
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
11002
|
+
ON CONFLICT(agent_id, source_kind, source_id) DO UPDATE SET
|
|
11003
|
+
status = excluded.status,
|
|
11004
|
+
context_eligible = excluded.context_eligible,
|
|
11005
|
+
reasons_json = excluded.reasons_json,
|
|
11006
|
+
policy_version = excluded.policy_version,
|
|
11007
|
+
scanned_at = excluded.scanned_at`);
|
|
11008
|
+
for (const row of rows) {
|
|
11009
|
+
const sourceId = row.source_id?.trim();
|
|
11010
|
+
if (!sourceId)
|
|
11011
|
+
continue;
|
|
11012
|
+
const assessment = scanMemoryContent(row.content ?? "");
|
|
11013
|
+
statement.run(row.agent_id?.trim() || "default", sourceKind, sourceId, assessment.status, assessment.contextEligible ? 1 : 0, JSON.stringify(assessment.reasons), MEMORY_CONTENT_SAFETY_POLICY_VERSION, scannedAt);
|
|
11014
|
+
}
|
|
11015
|
+
}
|
|
11016
|
+
function backfillTable(db, params) {
|
|
11017
|
+
if (!tableExists2(db, params.table) || !hasColumn24(db, params.table, params.sourceIdColumn) || !hasColumn24(db, params.table, params.contentColumn))
|
|
11018
|
+
return;
|
|
11019
|
+
const agentColumn = hasColumn24(db, params.table, "agent_id") ? "COALESCE(NULLIF(TRIM(agent_id), ''), 'default')" : "'default'";
|
|
11020
|
+
const rows = db.prepare(`SELECT ${agentColumn} AS agent_id, ${params.sourceIdColumn} AS source_id, ${params.contentColumn} AS content
|
|
11021
|
+
FROM ${params.table}${params.where ? ` WHERE ${params.where}` : ""}`).all();
|
|
11022
|
+
backfill(db, rows, params.sourceKind, params.scannedAt);
|
|
11023
|
+
}
|
|
11024
|
+
function up125(db) {
|
|
11025
|
+
db.exec(`
|
|
11026
|
+
CREATE TABLE IF NOT EXISTS memory_content_safety (
|
|
11027
|
+
agent_id TEXT NOT NULL,
|
|
11028
|
+
source_kind TEXT NOT NULL CHECK (source_kind IN ('memory', 'artifact', 'transcript', 'summary', 'source_chunk')),
|
|
11029
|
+
source_id TEXT NOT NULL,
|
|
11030
|
+
status TEXT NOT NULL CHECK (status IN ('clean', 'tainted', 'blocked')),
|
|
11031
|
+
context_eligible INTEGER NOT NULL CHECK (context_eligible IN (0, 1)),
|
|
11032
|
+
reasons_json TEXT NOT NULL DEFAULT '[]',
|
|
11033
|
+
policy_version TEXT NOT NULL,
|
|
11034
|
+
scanned_at TEXT NOT NULL,
|
|
11035
|
+
PRIMARY KEY (agent_id, source_kind, source_id)
|
|
11036
|
+
);
|
|
11037
|
+
|
|
11038
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_status
|
|
11039
|
+
ON memory_content_safety(agent_id, status, source_kind);
|
|
11040
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_eligibility
|
|
11041
|
+
ON memory_content_safety(agent_id, source_kind, context_eligible);
|
|
11042
|
+
`);
|
|
11043
|
+
const scannedAt = new Date().toISOString();
|
|
11044
|
+
backfillTable(db, {
|
|
11045
|
+
table: "memories",
|
|
11046
|
+
sourceKind: "memory",
|
|
11047
|
+
sourceIdColumn: "id",
|
|
11048
|
+
contentColumn: "content",
|
|
11049
|
+
scannedAt
|
|
11050
|
+
});
|
|
11051
|
+
backfillTable(db, {
|
|
11052
|
+
table: "memory_artifacts",
|
|
11053
|
+
sourceKind: "artifact",
|
|
11054
|
+
sourceIdColumn: "source_path",
|
|
11055
|
+
contentColumn: "content",
|
|
11056
|
+
scannedAt
|
|
11057
|
+
});
|
|
11058
|
+
backfillTable(db, {
|
|
11059
|
+
table: "session_transcripts",
|
|
11060
|
+
sourceKind: "transcript",
|
|
11061
|
+
sourceIdColumn: "session_key",
|
|
11062
|
+
contentColumn: "content",
|
|
11063
|
+
scannedAt
|
|
11064
|
+
});
|
|
11065
|
+
backfillTable(db, {
|
|
11066
|
+
table: "session_summaries",
|
|
11067
|
+
sourceKind: "summary",
|
|
11068
|
+
sourceIdColumn: "id",
|
|
11069
|
+
contentColumn: "content",
|
|
11070
|
+
scannedAt
|
|
11071
|
+
});
|
|
11072
|
+
backfillTable(db, {
|
|
11073
|
+
table: "embeddings",
|
|
11074
|
+
sourceKind: "source_chunk",
|
|
11075
|
+
sourceIdColumn: "id",
|
|
11076
|
+
contentColumn: "chunk_text",
|
|
11077
|
+
where: "source_type IN ('source_chunk', 'source_obsidian_chunk')",
|
|
11078
|
+
scannedAt
|
|
11079
|
+
});
|
|
11080
|
+
}
|
|
10899
11081
|
var MIGRATIONS = [
|
|
10900
11082
|
{
|
|
10901
11083
|
version: 1,
|
|
@@ -11904,6 +12086,12 @@ var MIGRATIONS = [
|
|
|
11904
12086
|
artifacts: {
|
|
11905
12087
|
tables: ["imported_source_lifecycle"]
|
|
11906
12088
|
}
|
|
12089
|
+
},
|
|
12090
|
+
{
|
|
12091
|
+
version: 125,
|
|
12092
|
+
name: "memory-content-safety",
|
|
12093
|
+
up: up125,
|
|
12094
|
+
artifacts: { tables: ["memory_content_safety"] }
|
|
11907
12095
|
}
|
|
11908
12096
|
];
|
|
11909
12097
|
var LATEST_SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0;
|
|
@@ -19121,6 +19309,99 @@ var PIPELINE_PROVIDER_CHOICES2 = [
|
|
|
19121
19309
|
var SYNTHESIS_PROVIDER_CHOICES2 = PIPELINE_PROVIDER_CHOICES2.filter((provider) => provider !== "command");
|
|
19122
19310
|
var PIPELINE_PROVIDER_SET2 = new Set(PIPELINE_PROVIDER_CHOICES2);
|
|
19123
19311
|
var SYNTHESIS_PROVIDER_SET2 = new Set(SYNTHESIS_PROVIDER_CHOICES2);
|
|
19312
|
+
var MEMORY_CONTENT_SAFETY_POLICY_VERSION2 = "memory-content-safety-v1";
|
|
19313
|
+
var MEMORY_CONTENT_SAFETY_REASONS2 = [
|
|
19314
|
+
"prompt_injection",
|
|
19315
|
+
"exfiltration",
|
|
19316
|
+
"credential_harvesting",
|
|
19317
|
+
"malicious_shell",
|
|
19318
|
+
"tool_directive",
|
|
19319
|
+
"invisible_unicode"
|
|
19320
|
+
];
|
|
19321
|
+
var INVISIBLE_UNICODE_RE2 = /(?:\u034f|[\u00ad\u061c\u070f\u180e\u200b\u200c\u200e\u200f\u202a-\u202e\u2060\u2066-\u2069\u206a-\u206f\ufeff]|[\u{e0000}-\u{e007f}])/u;
|
|
19322
|
+
var STRONG_DEFENSIVE_CONTEXT_RE2 = /\b(?:security\s+(?:guidance|discussion|analysis)|threat\s+model|defensive)\b/i;
|
|
19323
|
+
var REPORTING_CONTEXT_RE2 = /\b(?:example|illustrat\w*|sample|quote|quoted|detector|scanner|classif\w*)\b/i;
|
|
19324
|
+
var REPORTING_BEFORE_RE2 = /\b(?:example|illustrat\w*|sample|quote|quoted|detector|scanner|classif\w*)\b[\s\S]{0,80}\b(?:say\w*|read\w*|show\w*|flag\w*|detect\w*|describ\w*|demonstrat\w*|contain\w*|match\w*|pattern)\b/i;
|
|
19325
|
+
var REPORTING_AFTER_RE2 = /\b(?:detector|scanner|classif\w*|flag\w*|pattern|dangerous|unsafe|malicious|hostile|should|would|must|never|do not|don't|avoid|quoted)\b/i;
|
|
19326
|
+
var NEGATED_DIRECTIVE_RE2 = /\b(?:never|do not|don't|should not|must not|cannot|can't|avoid|prevent|detect|mitigat\w*)\b[\s\S]{0,80}$/i;
|
|
19327
|
+
var PROMPT_INJECTION_RES2 = [
|
|
19328
|
+
/\b(?:ignore|disregard|override|forget|bypass)\b[\s\S]{0,100}\b(?:previous|prior|above|earlier|system|developer|assistant|safety|security)?\s*(?:instructions?|rules?|prompt|message)\b/i,
|
|
19329
|
+
/\b(?:new|following|these)\s+(?:(?:system|developer|assistant|hidden)\s+)?instructions?\b/i,
|
|
19330
|
+
/(?:^|\n)\s*(?:system|developer|instruction|prompt)\s*:/im,
|
|
19331
|
+
/<\s*(?:system|developer|assistant|instruction|prompt)\b[^>]*>/i,
|
|
19332
|
+
/\b(?:you are now|act as|roleplay as|pretend to be)\b[\s\S]{0,80}\b(?:system|admin|developer|unrestricted|jailbreak|different agent)\b/i
|
|
19333
|
+
];
|
|
19334
|
+
var TOOL_DIRECTIVE_RES2 = [
|
|
19335
|
+
/<\s*(?:tool[_-]?call|function[_-]?call|invoke|tool)\b/i,
|
|
19336
|
+
/\b(?:assistant|system)\s+to\s*=\s*[a-z0-9_.-]+/i,
|
|
19337
|
+
/\b(?:call|invoke|use|run|execute)\s+(?:the\s+)?[a-z0-9_.-]+\s+tool\b/i
|
|
19338
|
+
];
|
|
19339
|
+
var EXFILTRATION_RE2 = /\b(?:reveal|show|print|send|upload|exfiltrat\w*|dump|forward|leak|transmit|export)\b[\s\S]{0,120}(?:\b(?:system\s+prompt|hidden\s+instructions?|secret(?:s)?|credential(?:s)?|password(?:s)?|api\s*keys?|tokens?|private\s+keys?|environment\s+variables?)\b|\.env\b|~\/(?:\.ssh)\/\S+|\/etc\/(?:shadow|passwd)\b)/i;
|
|
19340
|
+
var EXFILTRATION_REVERSE2 = /(?:\b(?:system\s+prompt|hidden\s+instructions?|secret(?:s)?|credential(?:s)?|password(?:s)?|api\s*keys?|tokens?|private\s+keys?|environment\s+variables?)\b|\.env\b|~\/(?:\.ssh)\/\S+|\/etc\/(?:shadow|passwd)\b)[\s\S]{0,120}\b(?:reveal|show|print|send|upload|exfiltrat\w*|dump|forward|leak|transmit|export)\b/i;
|
|
19341
|
+
var CREDENTIAL_HARVESTING_RE2 = /\b(?:enter|paste|provide|share|send|give|submit|type|hand over)\b[\s\S]{0,80}\b(?:password|api\s*key|token|secret|credential|private\s+key)\b/i;
|
|
19342
|
+
var DANGEROUS_SHELL_RE2 = /\b(?:curl|wget)\b[^\n]{0,240}\|\s*(?:ba|z|fi)?sh\b|\brm\s+-rf\s+(?:\/|~|\.ssh)[^\n]{0,240}|\b(?:cat|head|tail)\s+~\/?\.ssh\/(?:id_[a-z]+|authorized_keys)\b|\b(?:printenv|env)\b[^\n]{0,120}\b(?:curl|wget|send|upload|post)\b/i;
|
|
19343
|
+
function matchHasDefensiveContext2(content, match) {
|
|
19344
|
+
if (!match || !match[0])
|
|
19345
|
+
return false;
|
|
19346
|
+
const start = match.index ?? 0;
|
|
19347
|
+
const before = content.slice(Math.max(0, start - 120), start);
|
|
19348
|
+
const after = content.slice(start + match[0].length, start + match[0].length + 160);
|
|
19349
|
+
return STRONG_DEFENSIVE_CONTEXT_RE2.test(match[0]) || NEGATED_DIRECTIVE_RE2.test(before) || STRONG_DEFENSIVE_CONTEXT_RE2.test(before) || STRONG_DEFENSIVE_CONTEXT_RE2.test(after) || REPORTING_BEFORE_RE2.test(before) || REPORTING_CONTEXT_RE2.test(before) && REPORTING_AFTER_RE2.test(after);
|
|
19350
|
+
}
|
|
19351
|
+
function hasActionableMatch2(content, patterns) {
|
|
19352
|
+
return patterns.some((pattern) => {
|
|
19353
|
+
const flags = pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`;
|
|
19354
|
+
const searchable = new RegExp(pattern.source, flags);
|
|
19355
|
+
let match;
|
|
19356
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
19357
|
+
if (!matchHasDefensiveContext2(content, match))
|
|
19358
|
+
return true;
|
|
19359
|
+
if (match[0].length === 0)
|
|
19360
|
+
searchable.lastIndex += 1;
|
|
19361
|
+
}
|
|
19362
|
+
return false;
|
|
19363
|
+
});
|
|
19364
|
+
}
|
|
19365
|
+
function hasDangerousShell2(content) {
|
|
19366
|
+
const searchable = new RegExp(DANGEROUS_SHELL_RE2.source, `${DANGEROUS_SHELL_RE2.flags}g`);
|
|
19367
|
+
let match;
|
|
19368
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
19369
|
+
if (matchHasDefensiveContext2(content, match))
|
|
19370
|
+
continue;
|
|
19371
|
+
const end = (match.index ?? 0) + match[0].length;
|
|
19372
|
+
const after = content.slice(end, end + 160);
|
|
19373
|
+
if (!STRONG_DEFENSIVE_CONTEXT_RE2.test(after) && !REPORTING_AFTER_RE2.test(after))
|
|
19374
|
+
return true;
|
|
19375
|
+
if (match[0].length === 0)
|
|
19376
|
+
searchable.lastIndex += 1;
|
|
19377
|
+
}
|
|
19378
|
+
return false;
|
|
19379
|
+
}
|
|
19380
|
+
function scanMemoryContent2(content) {
|
|
19381
|
+
const raw = typeof content === "string" ? content : String(content ?? "");
|
|
19382
|
+
const normalized = raw.normalize("NFKC");
|
|
19383
|
+
const reasons = new Set;
|
|
19384
|
+
if (INVISIBLE_UNICODE_RE2.test(raw))
|
|
19385
|
+
reasons.add("invisible_unicode");
|
|
19386
|
+
if (hasActionableMatch2(normalized, PROMPT_INJECTION_RES2))
|
|
19387
|
+
reasons.add("prompt_injection");
|
|
19388
|
+
if (hasActionableMatch2(normalized, TOOL_DIRECTIVE_RES2))
|
|
19389
|
+
reasons.add("tool_directive");
|
|
19390
|
+
if (hasActionableMatch2(normalized, [EXFILTRATION_RE2, EXFILTRATION_REVERSE2]))
|
|
19391
|
+
reasons.add("exfiltration");
|
|
19392
|
+
if (hasActionableMatch2(normalized, [CREDENTIAL_HARVESTING_RE2]))
|
|
19393
|
+
reasons.add("credential_harvesting");
|
|
19394
|
+
if (hasDangerousShell2(normalized))
|
|
19395
|
+
reasons.add("malicious_shell");
|
|
19396
|
+
const orderedReasons = MEMORY_CONTENT_SAFETY_REASONS2.filter((reason) => reasons.has(reason));
|
|
19397
|
+
const status = orderedReasons.length === 0 ? "clean" : orderedReasons.every((reason) => reason === "invisible_unicode") ? "tainted" : "blocked";
|
|
19398
|
+
return {
|
|
19399
|
+
status,
|
|
19400
|
+
contextEligible: status === "clean",
|
|
19401
|
+
reasons: orderedReasons,
|
|
19402
|
+
policyVersion: MEMORY_CONTENT_SAFETY_POLICY_VERSION2
|
|
19403
|
+
};
|
|
19404
|
+
}
|
|
19124
19405
|
var DAEMON_DERIVED_MEMORY_SOURCE_TYPES2 = ["extract", "aggregate-recall", "session_end", "checkpoint", "dreaming"];
|
|
19125
19406
|
var MEMORIES_FTS_TOKENIZER2 = "unicode61";
|
|
19126
19407
|
function normalizeSql2(sql) {
|
|
@@ -19172,7 +19453,7 @@ function memoriesFtsNeedsTokenizerRepair2(sql) {
|
|
|
19172
19453
|
return true;
|
|
19173
19454
|
return !normalized.includes(`tokenize='${MEMORIES_FTS_TOKENIZER2}'`);
|
|
19174
19455
|
}
|
|
19175
|
-
function
|
|
19456
|
+
function up126(db) {
|
|
19176
19457
|
db.exec(`
|
|
19177
19458
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
19178
19459
|
version INTEGER PRIMARY KEY,
|
|
@@ -19261,12 +19542,12 @@ function up125(db) {
|
|
|
19261
19542
|
} catch {}
|
|
19262
19543
|
createMemoriesFts2(db);
|
|
19263
19544
|
}
|
|
19264
|
-
function
|
|
19545
|
+
function hasColumn25(db, table, column) {
|
|
19265
19546
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
19266
19547
|
return rows.some((r) => r.name === column);
|
|
19267
19548
|
}
|
|
19268
19549
|
function addColumnIfMissing27(db, table, column, definition) {
|
|
19269
|
-
if (!
|
|
19550
|
+
if (!hasColumn25(db, table, column)) {
|
|
19270
19551
|
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
19271
19552
|
}
|
|
19272
19553
|
}
|
|
@@ -19416,12 +19697,12 @@ function up310(db) {
|
|
|
19416
19697
|
WHERE content_hash IS NOT NULL AND is_deleted = 0
|
|
19417
19698
|
`);
|
|
19418
19699
|
}
|
|
19419
|
-
function
|
|
19700
|
+
function hasColumn26(db, table, column) {
|
|
19420
19701
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
19421
19702
|
return rows.some((r) => r.name === column);
|
|
19422
19703
|
}
|
|
19423
19704
|
function addColumnIfMissing32(db, table, column, definition) {
|
|
19424
|
-
if (!
|
|
19705
|
+
if (!hasColumn26(db, table, column)) {
|
|
19425
19706
|
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
19426
19707
|
}
|
|
19427
19708
|
}
|
|
@@ -19615,7 +19896,7 @@ function up1110(db) {
|
|
|
19615
19896
|
ON session_scores(session_key);
|
|
19616
19897
|
`);
|
|
19617
19898
|
}
|
|
19618
|
-
function
|
|
19899
|
+
function up127(db) {
|
|
19619
19900
|
db.exec(`
|
|
19620
19901
|
CREATE TABLE IF NOT EXISTS scheduled_tasks (
|
|
19621
19902
|
id TEXT PRIMARY KEY,
|
|
@@ -22407,7 +22688,7 @@ function up1032(db) {
|
|
|
22407
22688
|
)
|
|
22408
22689
|
`);
|
|
22409
22690
|
}
|
|
22410
|
-
function
|
|
22691
|
+
function tableExists3(db, table) {
|
|
22411
22692
|
return db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) !== undefined;
|
|
22412
22693
|
}
|
|
22413
22694
|
function hasColumn162(db, table, column) {
|
|
@@ -22429,7 +22710,7 @@ function up1042(db) {
|
|
|
22429
22710
|
CREATE INDEX IF NOT EXISTS idx_derived_memory_sources_source
|
|
22430
22711
|
ON derived_memory_sources(agent_id, source_kind, source_id);
|
|
22431
22712
|
`);
|
|
22432
|
-
if (
|
|
22713
|
+
if (tableExists3(db, "aggregate_evidence_sources")) {
|
|
22433
22714
|
db.exec(`
|
|
22434
22715
|
INSERT OR IGNORE INTO derived_memory_sources
|
|
22435
22716
|
(derived_memory_id, source_kind, source_id, source_path, agent_id, created_at)
|
|
@@ -22437,7 +22718,7 @@ function up1042(db) {
|
|
|
22437
22718
|
FROM aggregate_evidence_sources
|
|
22438
22719
|
`);
|
|
22439
22720
|
}
|
|
22440
|
-
if (
|
|
22721
|
+
if (tableExists3(db, "aggregate_memory_sources")) {
|
|
22441
22722
|
db.exec(`
|
|
22442
22723
|
INSERT OR IGNORE INTO derived_memory_sources
|
|
22443
22724
|
(derived_memory_id, source_kind, source_id, source_path, agent_id, created_at)
|
|
@@ -22445,10 +22726,10 @@ function up1042(db) {
|
|
|
22445
22726
|
FROM aggregate_memory_sources
|
|
22446
22727
|
`);
|
|
22447
22728
|
}
|
|
22448
|
-
if (
|
|
22729
|
+
if (tableExists3(db, "memories") && !hasColumn162(db, "memories", "stale_at")) {
|
|
22449
22730
|
db.exec("ALTER TABLE memories ADD COLUMN stale_at TEXT");
|
|
22450
22731
|
}
|
|
22451
|
-
if (
|
|
22732
|
+
if (tableExists3(db, "memories")) {
|
|
22452
22733
|
db.exec(`
|
|
22453
22734
|
CREATE INDEX IF NOT EXISTS idx_memories_stale_derived
|
|
22454
22735
|
ON memories(agent_id, stale_at)
|
|
@@ -23099,11 +23380,100 @@ function up1242(db) {
|
|
|
23099
23380
|
ON imported_source_lifecycle(agent_id, status, updated_at DESC);
|
|
23100
23381
|
`);
|
|
23101
23382
|
}
|
|
23383
|
+
function tableExists22(db, table) {
|
|
23384
|
+
return db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
23385
|
+
}
|
|
23386
|
+
function hasColumn242(db, table, column) {
|
|
23387
|
+
return db.prepare(`PRAGMA table_info("${table}")`).all().some((row) => row.name === column);
|
|
23388
|
+
}
|
|
23389
|
+
function backfill2(db, rows, sourceKind, scannedAt) {
|
|
23390
|
+
const statement = db.prepare(`INSERT INTO memory_content_safety
|
|
23391
|
+
(agent_id, source_kind, source_id, status, context_eligible, reasons_json, policy_version, scanned_at)
|
|
23392
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
23393
|
+
ON CONFLICT(agent_id, source_kind, source_id) DO UPDATE SET
|
|
23394
|
+
status = excluded.status,
|
|
23395
|
+
context_eligible = excluded.context_eligible,
|
|
23396
|
+
reasons_json = excluded.reasons_json,
|
|
23397
|
+
policy_version = excluded.policy_version,
|
|
23398
|
+
scanned_at = excluded.scanned_at`);
|
|
23399
|
+
for (const row of rows) {
|
|
23400
|
+
const sourceId = row.source_id?.trim();
|
|
23401
|
+
if (!sourceId)
|
|
23402
|
+
continue;
|
|
23403
|
+
const assessment = scanMemoryContent2(row.content ?? "");
|
|
23404
|
+
statement.run(row.agent_id?.trim() || "default", sourceKind, sourceId, assessment.status, assessment.contextEligible ? 1 : 0, JSON.stringify(assessment.reasons), MEMORY_CONTENT_SAFETY_POLICY_VERSION2, scannedAt);
|
|
23405
|
+
}
|
|
23406
|
+
}
|
|
23407
|
+
function backfillTable2(db, params) {
|
|
23408
|
+
if (!tableExists22(db, params.table) || !hasColumn242(db, params.table, params.sourceIdColumn) || !hasColumn242(db, params.table, params.contentColumn))
|
|
23409
|
+
return;
|
|
23410
|
+
const agentColumn = hasColumn242(db, params.table, "agent_id") ? "COALESCE(NULLIF(TRIM(agent_id), ''), 'default')" : "'default'";
|
|
23411
|
+
const rows = db.prepare(`SELECT ${agentColumn} AS agent_id, ${params.sourceIdColumn} AS source_id, ${params.contentColumn} AS content
|
|
23412
|
+
FROM ${params.table}${params.where ? ` WHERE ${params.where}` : ""}`).all();
|
|
23413
|
+
backfill2(db, rows, params.sourceKind, params.scannedAt);
|
|
23414
|
+
}
|
|
23415
|
+
function up1252(db) {
|
|
23416
|
+
db.exec(`
|
|
23417
|
+
CREATE TABLE IF NOT EXISTS memory_content_safety (
|
|
23418
|
+
agent_id TEXT NOT NULL,
|
|
23419
|
+
source_kind TEXT NOT NULL CHECK (source_kind IN ('memory', 'artifact', 'transcript', 'summary', 'source_chunk')),
|
|
23420
|
+
source_id TEXT NOT NULL,
|
|
23421
|
+
status TEXT NOT NULL CHECK (status IN ('clean', 'tainted', 'blocked')),
|
|
23422
|
+
context_eligible INTEGER NOT NULL CHECK (context_eligible IN (0, 1)),
|
|
23423
|
+
reasons_json TEXT NOT NULL DEFAULT '[]',
|
|
23424
|
+
policy_version TEXT NOT NULL,
|
|
23425
|
+
scanned_at TEXT NOT NULL,
|
|
23426
|
+
PRIMARY KEY (agent_id, source_kind, source_id)
|
|
23427
|
+
);
|
|
23428
|
+
|
|
23429
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_status
|
|
23430
|
+
ON memory_content_safety(agent_id, status, source_kind);
|
|
23431
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_eligibility
|
|
23432
|
+
ON memory_content_safety(agent_id, source_kind, context_eligible);
|
|
23433
|
+
`);
|
|
23434
|
+
const scannedAt = new Date().toISOString();
|
|
23435
|
+
backfillTable2(db, {
|
|
23436
|
+
table: "memories",
|
|
23437
|
+
sourceKind: "memory",
|
|
23438
|
+
sourceIdColumn: "id",
|
|
23439
|
+
contentColumn: "content",
|
|
23440
|
+
scannedAt
|
|
23441
|
+
});
|
|
23442
|
+
backfillTable2(db, {
|
|
23443
|
+
table: "memory_artifacts",
|
|
23444
|
+
sourceKind: "artifact",
|
|
23445
|
+
sourceIdColumn: "source_path",
|
|
23446
|
+
contentColumn: "content",
|
|
23447
|
+
scannedAt
|
|
23448
|
+
});
|
|
23449
|
+
backfillTable2(db, {
|
|
23450
|
+
table: "session_transcripts",
|
|
23451
|
+
sourceKind: "transcript",
|
|
23452
|
+
sourceIdColumn: "session_key",
|
|
23453
|
+
contentColumn: "content",
|
|
23454
|
+
scannedAt
|
|
23455
|
+
});
|
|
23456
|
+
backfillTable2(db, {
|
|
23457
|
+
table: "session_summaries",
|
|
23458
|
+
sourceKind: "summary",
|
|
23459
|
+
sourceIdColumn: "id",
|
|
23460
|
+
contentColumn: "content",
|
|
23461
|
+
scannedAt
|
|
23462
|
+
});
|
|
23463
|
+
backfillTable2(db, {
|
|
23464
|
+
table: "embeddings",
|
|
23465
|
+
sourceKind: "source_chunk",
|
|
23466
|
+
sourceIdColumn: "id",
|
|
23467
|
+
contentColumn: "chunk_text",
|
|
23468
|
+
where: "source_type IN ('source_chunk', 'source_obsidian_chunk')",
|
|
23469
|
+
scannedAt
|
|
23470
|
+
});
|
|
23471
|
+
}
|
|
23102
23472
|
var MIGRATIONS2 = [
|
|
23103
23473
|
{
|
|
23104
23474
|
version: 1,
|
|
23105
23475
|
name: "baseline",
|
|
23106
|
-
up:
|
|
23476
|
+
up: up126,
|
|
23107
23477
|
artifacts: { tables: ["memories", "conversations", "embeddings"] }
|
|
23108
23478
|
},
|
|
23109
23479
|
{
|
|
@@ -23175,7 +23545,7 @@ var MIGRATIONS2 = [
|
|
|
23175
23545
|
{
|
|
23176
23546
|
version: 12,
|
|
23177
23547
|
name: "scheduled-tasks",
|
|
23178
|
-
up:
|
|
23548
|
+
up: up127,
|
|
23179
23549
|
artifacts: { tables: ["scheduled_tasks", "task_runs"] }
|
|
23180
23550
|
},
|
|
23181
23551
|
{
|
|
@@ -24107,6 +24477,12 @@ var MIGRATIONS2 = [
|
|
|
24107
24477
|
artifacts: {
|
|
24108
24478
|
tables: ["imported_source_lifecycle"]
|
|
24109
24479
|
}
|
|
24480
|
+
},
|
|
24481
|
+
{
|
|
24482
|
+
version: 125,
|
|
24483
|
+
name: "memory-content-safety",
|
|
24484
|
+
up: up1252,
|
|
24485
|
+
artifacts: { tables: ["memory_content_safety"] }
|
|
24110
24486
|
}
|
|
24111
24487
|
];
|
|
24112
24488
|
var LATEST_SCHEMA_VERSION2 = MIGRATIONS2[MIGRATIONS2.length - 1]?.version ?? 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signetai/connector-hermes-agent",
|
|
3
|
-
"version": "0.193.
|
|
3
|
+
"version": "0.193.2",
|
|
4
4
|
"description": "Signet connector for Hermes Agent — installs Signet as a pluggable memory provider",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"typecheck": "tsc --noEmit"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@signetai/connector-base": "0.193.
|
|
29
|
-
"@signetai/core": "0.193.
|
|
28
|
+
"@signetai/connector-base": "0.193.2",
|
|
29
|
+
"@signetai/core": "0.193.2"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/node": "^22.0.0",
|