@signetai/connector-openclaw 0.193.1 → 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
|
@@ -6915,6 +6915,99 @@ var PIPELINE_PROVIDER_CHOICES = [
|
|
|
6915
6915
|
var SYNTHESIS_PROVIDER_CHOICES = PIPELINE_PROVIDER_CHOICES.filter((provider) => provider !== "command");
|
|
6916
6916
|
var PIPELINE_PROVIDER_SET = new Set(PIPELINE_PROVIDER_CHOICES);
|
|
6917
6917
|
var SYNTHESIS_PROVIDER_SET = new Set(SYNTHESIS_PROVIDER_CHOICES);
|
|
6918
|
+
var MEMORY_CONTENT_SAFETY_POLICY_VERSION = "memory-content-safety-v1";
|
|
6919
|
+
var MEMORY_CONTENT_SAFETY_REASONS = [
|
|
6920
|
+
"prompt_injection",
|
|
6921
|
+
"exfiltration",
|
|
6922
|
+
"credential_harvesting",
|
|
6923
|
+
"malicious_shell",
|
|
6924
|
+
"tool_directive",
|
|
6925
|
+
"invisible_unicode"
|
|
6926
|
+
];
|
|
6927
|
+
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;
|
|
6928
|
+
var STRONG_DEFENSIVE_CONTEXT_RE = /\b(?:security\s+(?:guidance|discussion|analysis)|threat\s+model|defensive)\b/i;
|
|
6929
|
+
var REPORTING_CONTEXT_RE = /\b(?:example|illustrat\w*|sample|quote|quoted|detector|scanner|classif\w*)\b/i;
|
|
6930
|
+
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;
|
|
6931
|
+
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;
|
|
6932
|
+
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;
|
|
6933
|
+
var PROMPT_INJECTION_RES = [
|
|
6934
|
+
/\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,
|
|
6935
|
+
/\b(?:new|following|these)\s+(?:(?:system|developer|assistant|hidden)\s+)?instructions?\b/i,
|
|
6936
|
+
/(?:^|\n)\s*(?:system|developer|instruction|prompt)\s*:/im,
|
|
6937
|
+
/<\s*(?:system|developer|assistant|instruction|prompt)\b[^>]*>/i,
|
|
6938
|
+
/\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
|
|
6939
|
+
];
|
|
6940
|
+
var TOOL_DIRECTIVE_RES = [
|
|
6941
|
+
/<\s*(?:tool[_-]?call|function[_-]?call|invoke|tool)\b/i,
|
|
6942
|
+
/\b(?:assistant|system)\s+to\s*=\s*[a-z0-9_.-]+/i,
|
|
6943
|
+
/\b(?:call|invoke|use|run|execute)\s+(?:the\s+)?[a-z0-9_.-]+\s+tool\b/i
|
|
6944
|
+
];
|
|
6945
|
+
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;
|
|
6946
|
+
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;
|
|
6947
|
+
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;
|
|
6948
|
+
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;
|
|
6949
|
+
function matchHasDefensiveContext(content, match) {
|
|
6950
|
+
if (!match || !match[0])
|
|
6951
|
+
return false;
|
|
6952
|
+
const start = match.index ?? 0;
|
|
6953
|
+
const before = content.slice(Math.max(0, start - 120), start);
|
|
6954
|
+
const after = content.slice(start + match[0].length, start + match[0].length + 160);
|
|
6955
|
+
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);
|
|
6956
|
+
}
|
|
6957
|
+
function hasActionableMatch(content, patterns) {
|
|
6958
|
+
return patterns.some((pattern) => {
|
|
6959
|
+
const flags = pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`;
|
|
6960
|
+
const searchable = new RegExp(pattern.source, flags);
|
|
6961
|
+
let match;
|
|
6962
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
6963
|
+
if (!matchHasDefensiveContext(content, match))
|
|
6964
|
+
return true;
|
|
6965
|
+
if (match[0].length === 0)
|
|
6966
|
+
searchable.lastIndex += 1;
|
|
6967
|
+
}
|
|
6968
|
+
return false;
|
|
6969
|
+
});
|
|
6970
|
+
}
|
|
6971
|
+
function hasDangerousShell(content) {
|
|
6972
|
+
const searchable = new RegExp(DANGEROUS_SHELL_RE.source, `${DANGEROUS_SHELL_RE.flags}g`);
|
|
6973
|
+
let match;
|
|
6974
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
6975
|
+
if (matchHasDefensiveContext(content, match))
|
|
6976
|
+
continue;
|
|
6977
|
+
const end = (match.index ?? 0) + match[0].length;
|
|
6978
|
+
const after = content.slice(end, end + 160);
|
|
6979
|
+
if (!STRONG_DEFENSIVE_CONTEXT_RE.test(after) && !REPORTING_AFTER_RE.test(after))
|
|
6980
|
+
return true;
|
|
6981
|
+
if (match[0].length === 0)
|
|
6982
|
+
searchable.lastIndex += 1;
|
|
6983
|
+
}
|
|
6984
|
+
return false;
|
|
6985
|
+
}
|
|
6986
|
+
function scanMemoryContent(content) {
|
|
6987
|
+
const raw = typeof content === "string" ? content : String(content ?? "");
|
|
6988
|
+
const normalized = raw.normalize("NFKC");
|
|
6989
|
+
const reasons = new Set;
|
|
6990
|
+
if (INVISIBLE_UNICODE_RE.test(raw))
|
|
6991
|
+
reasons.add("invisible_unicode");
|
|
6992
|
+
if (hasActionableMatch(normalized, PROMPT_INJECTION_RES))
|
|
6993
|
+
reasons.add("prompt_injection");
|
|
6994
|
+
if (hasActionableMatch(normalized, TOOL_DIRECTIVE_RES))
|
|
6995
|
+
reasons.add("tool_directive");
|
|
6996
|
+
if (hasActionableMatch(normalized, [EXFILTRATION_RE, EXFILTRATION_REVERSE]))
|
|
6997
|
+
reasons.add("exfiltration");
|
|
6998
|
+
if (hasActionableMatch(normalized, [CREDENTIAL_HARVESTING_RE]))
|
|
6999
|
+
reasons.add("credential_harvesting");
|
|
7000
|
+
if (hasDangerousShell(normalized))
|
|
7001
|
+
reasons.add("malicious_shell");
|
|
7002
|
+
const orderedReasons = MEMORY_CONTENT_SAFETY_REASONS.filter((reason) => reasons.has(reason));
|
|
7003
|
+
const status = orderedReasons.length === 0 ? "clean" : orderedReasons.every((reason) => reason === "invisible_unicode") ? "tainted" : "blocked";
|
|
7004
|
+
return {
|
|
7005
|
+
status,
|
|
7006
|
+
contextEligible: status === "clean",
|
|
7007
|
+
reasons: orderedReasons,
|
|
7008
|
+
policyVersion: MEMORY_CONTENT_SAFETY_POLICY_VERSION
|
|
7009
|
+
};
|
|
7010
|
+
}
|
|
6918
7011
|
var DAEMON_DERIVED_MEMORY_SOURCE_TYPES = ["extract", "aggregate-recall", "session_end", "checkpoint", "dreaming"];
|
|
6919
7012
|
var MEMORIES_FTS_TOKENIZER = "unicode61";
|
|
6920
7013
|
function normalizeSql(sql) {
|
|
@@ -10893,6 +10986,95 @@ function up124(db) {
|
|
|
10893
10986
|
ON imported_source_lifecycle(agent_id, status, updated_at DESC);
|
|
10894
10987
|
`);
|
|
10895
10988
|
}
|
|
10989
|
+
function tableExists2(db, table) {
|
|
10990
|
+
return db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
10991
|
+
}
|
|
10992
|
+
function hasColumn24(db, table, column) {
|
|
10993
|
+
return db.prepare(`PRAGMA table_info("${table}")`).all().some((row) => row.name === column);
|
|
10994
|
+
}
|
|
10995
|
+
function backfill(db, rows, sourceKind, scannedAt) {
|
|
10996
|
+
const statement = db.prepare(`INSERT INTO memory_content_safety
|
|
10997
|
+
(agent_id, source_kind, source_id, status, context_eligible, reasons_json, policy_version, scanned_at)
|
|
10998
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
10999
|
+
ON CONFLICT(agent_id, source_kind, source_id) DO UPDATE SET
|
|
11000
|
+
status = excluded.status,
|
|
11001
|
+
context_eligible = excluded.context_eligible,
|
|
11002
|
+
reasons_json = excluded.reasons_json,
|
|
11003
|
+
policy_version = excluded.policy_version,
|
|
11004
|
+
scanned_at = excluded.scanned_at`);
|
|
11005
|
+
for (const row of rows) {
|
|
11006
|
+
const sourceId = row.source_id?.trim();
|
|
11007
|
+
if (!sourceId)
|
|
11008
|
+
continue;
|
|
11009
|
+
const assessment = scanMemoryContent(row.content ?? "");
|
|
11010
|
+
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);
|
|
11011
|
+
}
|
|
11012
|
+
}
|
|
11013
|
+
function backfillTable(db, params) {
|
|
11014
|
+
if (!tableExists2(db, params.table) || !hasColumn24(db, params.table, params.sourceIdColumn) || !hasColumn24(db, params.table, params.contentColumn))
|
|
11015
|
+
return;
|
|
11016
|
+
const agentColumn = hasColumn24(db, params.table, "agent_id") ? "COALESCE(NULLIF(TRIM(agent_id), ''), 'default')" : "'default'";
|
|
11017
|
+
const rows = db.prepare(`SELECT ${agentColumn} AS agent_id, ${params.sourceIdColumn} AS source_id, ${params.contentColumn} AS content
|
|
11018
|
+
FROM ${params.table}${params.where ? ` WHERE ${params.where}` : ""}`).all();
|
|
11019
|
+
backfill(db, rows, params.sourceKind, params.scannedAt);
|
|
11020
|
+
}
|
|
11021
|
+
function up125(db) {
|
|
11022
|
+
db.exec(`
|
|
11023
|
+
CREATE TABLE IF NOT EXISTS memory_content_safety (
|
|
11024
|
+
agent_id TEXT NOT NULL,
|
|
11025
|
+
source_kind TEXT NOT NULL CHECK (source_kind IN ('memory', 'artifact', 'transcript', 'summary', 'source_chunk')),
|
|
11026
|
+
source_id TEXT NOT NULL,
|
|
11027
|
+
status TEXT NOT NULL CHECK (status IN ('clean', 'tainted', 'blocked')),
|
|
11028
|
+
context_eligible INTEGER NOT NULL CHECK (context_eligible IN (0, 1)),
|
|
11029
|
+
reasons_json TEXT NOT NULL DEFAULT '[]',
|
|
11030
|
+
policy_version TEXT NOT NULL,
|
|
11031
|
+
scanned_at TEXT NOT NULL,
|
|
11032
|
+
PRIMARY KEY (agent_id, source_kind, source_id)
|
|
11033
|
+
);
|
|
11034
|
+
|
|
11035
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_status
|
|
11036
|
+
ON memory_content_safety(agent_id, status, source_kind);
|
|
11037
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_eligibility
|
|
11038
|
+
ON memory_content_safety(agent_id, source_kind, context_eligible);
|
|
11039
|
+
`);
|
|
11040
|
+
const scannedAt = new Date().toISOString();
|
|
11041
|
+
backfillTable(db, {
|
|
11042
|
+
table: "memories",
|
|
11043
|
+
sourceKind: "memory",
|
|
11044
|
+
sourceIdColumn: "id",
|
|
11045
|
+
contentColumn: "content",
|
|
11046
|
+
scannedAt
|
|
11047
|
+
});
|
|
11048
|
+
backfillTable(db, {
|
|
11049
|
+
table: "memory_artifacts",
|
|
11050
|
+
sourceKind: "artifact",
|
|
11051
|
+
sourceIdColumn: "source_path",
|
|
11052
|
+
contentColumn: "content",
|
|
11053
|
+
scannedAt
|
|
11054
|
+
});
|
|
11055
|
+
backfillTable(db, {
|
|
11056
|
+
table: "session_transcripts",
|
|
11057
|
+
sourceKind: "transcript",
|
|
11058
|
+
sourceIdColumn: "session_key",
|
|
11059
|
+
contentColumn: "content",
|
|
11060
|
+
scannedAt
|
|
11061
|
+
});
|
|
11062
|
+
backfillTable(db, {
|
|
11063
|
+
table: "session_summaries",
|
|
11064
|
+
sourceKind: "summary",
|
|
11065
|
+
sourceIdColumn: "id",
|
|
11066
|
+
contentColumn: "content",
|
|
11067
|
+
scannedAt
|
|
11068
|
+
});
|
|
11069
|
+
backfillTable(db, {
|
|
11070
|
+
table: "embeddings",
|
|
11071
|
+
sourceKind: "source_chunk",
|
|
11072
|
+
sourceIdColumn: "id",
|
|
11073
|
+
contentColumn: "chunk_text",
|
|
11074
|
+
where: "source_type IN ('source_chunk', 'source_obsidian_chunk')",
|
|
11075
|
+
scannedAt
|
|
11076
|
+
});
|
|
11077
|
+
}
|
|
10896
11078
|
var MIGRATIONS = [
|
|
10897
11079
|
{
|
|
10898
11080
|
version: 1,
|
|
@@ -11901,6 +12083,12 @@ var MIGRATIONS = [
|
|
|
11901
12083
|
artifacts: {
|
|
11902
12084
|
tables: ["imported_source_lifecycle"]
|
|
11903
12085
|
}
|
|
12086
|
+
},
|
|
12087
|
+
{
|
|
12088
|
+
version: 125,
|
|
12089
|
+
name: "memory-content-safety",
|
|
12090
|
+
up: up125,
|
|
12091
|
+
artifacts: { tables: ["memory_content_safety"] }
|
|
11904
12092
|
}
|
|
11905
12093
|
];
|
|
11906
12094
|
var LATEST_SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0;
|
|
@@ -21117,6 +21305,99 @@ var PIPELINE_PROVIDER_CHOICES2 = [
|
|
|
21117
21305
|
var SYNTHESIS_PROVIDER_CHOICES2 = PIPELINE_PROVIDER_CHOICES2.filter((provider) => provider !== "command");
|
|
21118
21306
|
var PIPELINE_PROVIDER_SET2 = new Set(PIPELINE_PROVIDER_CHOICES2);
|
|
21119
21307
|
var SYNTHESIS_PROVIDER_SET2 = new Set(SYNTHESIS_PROVIDER_CHOICES2);
|
|
21308
|
+
var MEMORY_CONTENT_SAFETY_POLICY_VERSION2 = "memory-content-safety-v1";
|
|
21309
|
+
var MEMORY_CONTENT_SAFETY_REASONS2 = [
|
|
21310
|
+
"prompt_injection",
|
|
21311
|
+
"exfiltration",
|
|
21312
|
+
"credential_harvesting",
|
|
21313
|
+
"malicious_shell",
|
|
21314
|
+
"tool_directive",
|
|
21315
|
+
"invisible_unicode"
|
|
21316
|
+
];
|
|
21317
|
+
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;
|
|
21318
|
+
var STRONG_DEFENSIVE_CONTEXT_RE2 = /\b(?:security\s+(?:guidance|discussion|analysis)|threat\s+model|defensive)\b/i;
|
|
21319
|
+
var REPORTING_CONTEXT_RE2 = /\b(?:example|illustrat\w*|sample|quote|quoted|detector|scanner|classif\w*)\b/i;
|
|
21320
|
+
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;
|
|
21321
|
+
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;
|
|
21322
|
+
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;
|
|
21323
|
+
var PROMPT_INJECTION_RES2 = [
|
|
21324
|
+
/\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,
|
|
21325
|
+
/\b(?:new|following|these)\s+(?:(?:system|developer|assistant|hidden)\s+)?instructions?\b/i,
|
|
21326
|
+
/(?:^|\n)\s*(?:system|developer|instruction|prompt)\s*:/im,
|
|
21327
|
+
/<\s*(?:system|developer|assistant|instruction|prompt)\b[^>]*>/i,
|
|
21328
|
+
/\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
|
|
21329
|
+
];
|
|
21330
|
+
var TOOL_DIRECTIVE_RES2 = [
|
|
21331
|
+
/<\s*(?:tool[_-]?call|function[_-]?call|invoke|tool)\b/i,
|
|
21332
|
+
/\b(?:assistant|system)\s+to\s*=\s*[a-z0-9_.-]+/i,
|
|
21333
|
+
/\b(?:call|invoke|use|run|execute)\s+(?:the\s+)?[a-z0-9_.-]+\s+tool\b/i
|
|
21334
|
+
];
|
|
21335
|
+
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;
|
|
21336
|
+
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;
|
|
21337
|
+
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;
|
|
21338
|
+
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;
|
|
21339
|
+
function matchHasDefensiveContext2(content, match) {
|
|
21340
|
+
if (!match || !match[0])
|
|
21341
|
+
return false;
|
|
21342
|
+
const start = match.index ?? 0;
|
|
21343
|
+
const before = content.slice(Math.max(0, start - 120), start);
|
|
21344
|
+
const after = content.slice(start + match[0].length, start + match[0].length + 160);
|
|
21345
|
+
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);
|
|
21346
|
+
}
|
|
21347
|
+
function hasActionableMatch2(content, patterns) {
|
|
21348
|
+
return patterns.some((pattern) => {
|
|
21349
|
+
const flags = pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`;
|
|
21350
|
+
const searchable = new RegExp(pattern.source, flags);
|
|
21351
|
+
let match;
|
|
21352
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
21353
|
+
if (!matchHasDefensiveContext2(content, match))
|
|
21354
|
+
return true;
|
|
21355
|
+
if (match[0].length === 0)
|
|
21356
|
+
searchable.lastIndex += 1;
|
|
21357
|
+
}
|
|
21358
|
+
return false;
|
|
21359
|
+
});
|
|
21360
|
+
}
|
|
21361
|
+
function hasDangerousShell2(content) {
|
|
21362
|
+
const searchable = new RegExp(DANGEROUS_SHELL_RE2.source, `${DANGEROUS_SHELL_RE2.flags}g`);
|
|
21363
|
+
let match;
|
|
21364
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
21365
|
+
if (matchHasDefensiveContext2(content, match))
|
|
21366
|
+
continue;
|
|
21367
|
+
const end = (match.index ?? 0) + match[0].length;
|
|
21368
|
+
const after = content.slice(end, end + 160);
|
|
21369
|
+
if (!STRONG_DEFENSIVE_CONTEXT_RE2.test(after) && !REPORTING_AFTER_RE2.test(after))
|
|
21370
|
+
return true;
|
|
21371
|
+
if (match[0].length === 0)
|
|
21372
|
+
searchable.lastIndex += 1;
|
|
21373
|
+
}
|
|
21374
|
+
return false;
|
|
21375
|
+
}
|
|
21376
|
+
function scanMemoryContent2(content) {
|
|
21377
|
+
const raw = typeof content === "string" ? content : String(content ?? "");
|
|
21378
|
+
const normalized = raw.normalize("NFKC");
|
|
21379
|
+
const reasons = new Set;
|
|
21380
|
+
if (INVISIBLE_UNICODE_RE2.test(raw))
|
|
21381
|
+
reasons.add("invisible_unicode");
|
|
21382
|
+
if (hasActionableMatch2(normalized, PROMPT_INJECTION_RES2))
|
|
21383
|
+
reasons.add("prompt_injection");
|
|
21384
|
+
if (hasActionableMatch2(normalized, TOOL_DIRECTIVE_RES2))
|
|
21385
|
+
reasons.add("tool_directive");
|
|
21386
|
+
if (hasActionableMatch2(normalized, [EXFILTRATION_RE2, EXFILTRATION_REVERSE2]))
|
|
21387
|
+
reasons.add("exfiltration");
|
|
21388
|
+
if (hasActionableMatch2(normalized, [CREDENTIAL_HARVESTING_RE2]))
|
|
21389
|
+
reasons.add("credential_harvesting");
|
|
21390
|
+
if (hasDangerousShell2(normalized))
|
|
21391
|
+
reasons.add("malicious_shell");
|
|
21392
|
+
const orderedReasons = MEMORY_CONTENT_SAFETY_REASONS2.filter((reason) => reasons.has(reason));
|
|
21393
|
+
const status = orderedReasons.length === 0 ? "clean" : orderedReasons.every((reason) => reason === "invisible_unicode") ? "tainted" : "blocked";
|
|
21394
|
+
return {
|
|
21395
|
+
status,
|
|
21396
|
+
contextEligible: status === "clean",
|
|
21397
|
+
reasons: orderedReasons,
|
|
21398
|
+
policyVersion: MEMORY_CONTENT_SAFETY_POLICY_VERSION2
|
|
21399
|
+
};
|
|
21400
|
+
}
|
|
21120
21401
|
var DAEMON_DERIVED_MEMORY_SOURCE_TYPES2 = ["extract", "aggregate-recall", "session_end", "checkpoint", "dreaming"];
|
|
21121
21402
|
var MEMORIES_FTS_TOKENIZER2 = "unicode61";
|
|
21122
21403
|
function normalizeSql2(sql) {
|
|
@@ -21168,7 +21449,7 @@ function memoriesFtsNeedsTokenizerRepair2(sql) {
|
|
|
21168
21449
|
return true;
|
|
21169
21450
|
return !normalized.includes(`tokenize='${MEMORIES_FTS_TOKENIZER2}'`);
|
|
21170
21451
|
}
|
|
21171
|
-
function
|
|
21452
|
+
function up126(db) {
|
|
21172
21453
|
db.exec(`
|
|
21173
21454
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
21174
21455
|
version INTEGER PRIMARY KEY,
|
|
@@ -21257,12 +21538,12 @@ function up125(db) {
|
|
|
21257
21538
|
} catch {}
|
|
21258
21539
|
createMemoriesFts2(db);
|
|
21259
21540
|
}
|
|
21260
|
-
function
|
|
21541
|
+
function hasColumn25(db, table, column) {
|
|
21261
21542
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
21262
21543
|
return rows.some((r) => r.name === column);
|
|
21263
21544
|
}
|
|
21264
21545
|
function addColumnIfMissing27(db, table, column, definition) {
|
|
21265
|
-
if (!
|
|
21546
|
+
if (!hasColumn25(db, table, column)) {
|
|
21266
21547
|
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
21267
21548
|
}
|
|
21268
21549
|
}
|
|
@@ -21412,12 +21693,12 @@ function up310(db) {
|
|
|
21412
21693
|
WHERE content_hash IS NOT NULL AND is_deleted = 0
|
|
21413
21694
|
`);
|
|
21414
21695
|
}
|
|
21415
|
-
function
|
|
21696
|
+
function hasColumn26(db, table, column) {
|
|
21416
21697
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
21417
21698
|
return rows.some((r) => r.name === column);
|
|
21418
21699
|
}
|
|
21419
21700
|
function addColumnIfMissing32(db, table, column, definition) {
|
|
21420
|
-
if (!
|
|
21701
|
+
if (!hasColumn26(db, table, column)) {
|
|
21421
21702
|
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
21422
21703
|
}
|
|
21423
21704
|
}
|
|
@@ -21611,7 +21892,7 @@ function up1110(db) {
|
|
|
21611
21892
|
ON session_scores(session_key);
|
|
21612
21893
|
`);
|
|
21613
21894
|
}
|
|
21614
|
-
function
|
|
21895
|
+
function up127(db) {
|
|
21615
21896
|
db.exec(`
|
|
21616
21897
|
CREATE TABLE IF NOT EXISTS scheduled_tasks (
|
|
21617
21898
|
id TEXT PRIMARY KEY,
|
|
@@ -24403,7 +24684,7 @@ function up1032(db) {
|
|
|
24403
24684
|
)
|
|
24404
24685
|
`);
|
|
24405
24686
|
}
|
|
24406
|
-
function
|
|
24687
|
+
function tableExists3(db, table) {
|
|
24407
24688
|
return db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) !== undefined;
|
|
24408
24689
|
}
|
|
24409
24690
|
function hasColumn162(db, table, column) {
|
|
@@ -24425,7 +24706,7 @@ function up1042(db) {
|
|
|
24425
24706
|
CREATE INDEX IF NOT EXISTS idx_derived_memory_sources_source
|
|
24426
24707
|
ON derived_memory_sources(agent_id, source_kind, source_id);
|
|
24427
24708
|
`);
|
|
24428
|
-
if (
|
|
24709
|
+
if (tableExists3(db, "aggregate_evidence_sources")) {
|
|
24429
24710
|
db.exec(`
|
|
24430
24711
|
INSERT OR IGNORE INTO derived_memory_sources
|
|
24431
24712
|
(derived_memory_id, source_kind, source_id, source_path, agent_id, created_at)
|
|
@@ -24433,7 +24714,7 @@ function up1042(db) {
|
|
|
24433
24714
|
FROM aggregate_evidence_sources
|
|
24434
24715
|
`);
|
|
24435
24716
|
}
|
|
24436
|
-
if (
|
|
24717
|
+
if (tableExists3(db, "aggregate_memory_sources")) {
|
|
24437
24718
|
db.exec(`
|
|
24438
24719
|
INSERT OR IGNORE INTO derived_memory_sources
|
|
24439
24720
|
(derived_memory_id, source_kind, source_id, source_path, agent_id, created_at)
|
|
@@ -24441,10 +24722,10 @@ function up1042(db) {
|
|
|
24441
24722
|
FROM aggregate_memory_sources
|
|
24442
24723
|
`);
|
|
24443
24724
|
}
|
|
24444
|
-
if (
|
|
24725
|
+
if (tableExists3(db, "memories") && !hasColumn162(db, "memories", "stale_at")) {
|
|
24445
24726
|
db.exec("ALTER TABLE memories ADD COLUMN stale_at TEXT");
|
|
24446
24727
|
}
|
|
24447
|
-
if (
|
|
24728
|
+
if (tableExists3(db, "memories")) {
|
|
24448
24729
|
db.exec(`
|
|
24449
24730
|
CREATE INDEX IF NOT EXISTS idx_memories_stale_derived
|
|
24450
24731
|
ON memories(agent_id, stale_at)
|
|
@@ -25095,11 +25376,100 @@ function up1242(db) {
|
|
|
25095
25376
|
ON imported_source_lifecycle(agent_id, status, updated_at DESC);
|
|
25096
25377
|
`);
|
|
25097
25378
|
}
|
|
25379
|
+
function tableExists22(db, table) {
|
|
25380
|
+
return db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
25381
|
+
}
|
|
25382
|
+
function hasColumn242(db, table, column) {
|
|
25383
|
+
return db.prepare(`PRAGMA table_info("${table}")`).all().some((row) => row.name === column);
|
|
25384
|
+
}
|
|
25385
|
+
function backfill2(db, rows, sourceKind, scannedAt) {
|
|
25386
|
+
const statement = db.prepare(`INSERT INTO memory_content_safety
|
|
25387
|
+
(agent_id, source_kind, source_id, status, context_eligible, reasons_json, policy_version, scanned_at)
|
|
25388
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
25389
|
+
ON CONFLICT(agent_id, source_kind, source_id) DO UPDATE SET
|
|
25390
|
+
status = excluded.status,
|
|
25391
|
+
context_eligible = excluded.context_eligible,
|
|
25392
|
+
reasons_json = excluded.reasons_json,
|
|
25393
|
+
policy_version = excluded.policy_version,
|
|
25394
|
+
scanned_at = excluded.scanned_at`);
|
|
25395
|
+
for (const row of rows) {
|
|
25396
|
+
const sourceId = row.source_id?.trim();
|
|
25397
|
+
if (!sourceId)
|
|
25398
|
+
continue;
|
|
25399
|
+
const assessment = scanMemoryContent2(row.content ?? "");
|
|
25400
|
+
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);
|
|
25401
|
+
}
|
|
25402
|
+
}
|
|
25403
|
+
function backfillTable2(db, params) {
|
|
25404
|
+
if (!tableExists22(db, params.table) || !hasColumn242(db, params.table, params.sourceIdColumn) || !hasColumn242(db, params.table, params.contentColumn))
|
|
25405
|
+
return;
|
|
25406
|
+
const agentColumn = hasColumn242(db, params.table, "agent_id") ? "COALESCE(NULLIF(TRIM(agent_id), ''), 'default')" : "'default'";
|
|
25407
|
+
const rows = db.prepare(`SELECT ${agentColumn} AS agent_id, ${params.sourceIdColumn} AS source_id, ${params.contentColumn} AS content
|
|
25408
|
+
FROM ${params.table}${params.where ? ` WHERE ${params.where}` : ""}`).all();
|
|
25409
|
+
backfill2(db, rows, params.sourceKind, params.scannedAt);
|
|
25410
|
+
}
|
|
25411
|
+
function up1252(db) {
|
|
25412
|
+
db.exec(`
|
|
25413
|
+
CREATE TABLE IF NOT EXISTS memory_content_safety (
|
|
25414
|
+
agent_id TEXT NOT NULL,
|
|
25415
|
+
source_kind TEXT NOT NULL CHECK (source_kind IN ('memory', 'artifact', 'transcript', 'summary', 'source_chunk')),
|
|
25416
|
+
source_id TEXT NOT NULL,
|
|
25417
|
+
status TEXT NOT NULL CHECK (status IN ('clean', 'tainted', 'blocked')),
|
|
25418
|
+
context_eligible INTEGER NOT NULL CHECK (context_eligible IN (0, 1)),
|
|
25419
|
+
reasons_json TEXT NOT NULL DEFAULT '[]',
|
|
25420
|
+
policy_version TEXT NOT NULL,
|
|
25421
|
+
scanned_at TEXT NOT NULL,
|
|
25422
|
+
PRIMARY KEY (agent_id, source_kind, source_id)
|
|
25423
|
+
);
|
|
25424
|
+
|
|
25425
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_status
|
|
25426
|
+
ON memory_content_safety(agent_id, status, source_kind);
|
|
25427
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_eligibility
|
|
25428
|
+
ON memory_content_safety(agent_id, source_kind, context_eligible);
|
|
25429
|
+
`);
|
|
25430
|
+
const scannedAt = new Date().toISOString();
|
|
25431
|
+
backfillTable2(db, {
|
|
25432
|
+
table: "memories",
|
|
25433
|
+
sourceKind: "memory",
|
|
25434
|
+
sourceIdColumn: "id",
|
|
25435
|
+
contentColumn: "content",
|
|
25436
|
+
scannedAt
|
|
25437
|
+
});
|
|
25438
|
+
backfillTable2(db, {
|
|
25439
|
+
table: "memory_artifacts",
|
|
25440
|
+
sourceKind: "artifact",
|
|
25441
|
+
sourceIdColumn: "source_path",
|
|
25442
|
+
contentColumn: "content",
|
|
25443
|
+
scannedAt
|
|
25444
|
+
});
|
|
25445
|
+
backfillTable2(db, {
|
|
25446
|
+
table: "session_transcripts",
|
|
25447
|
+
sourceKind: "transcript",
|
|
25448
|
+
sourceIdColumn: "session_key",
|
|
25449
|
+
contentColumn: "content",
|
|
25450
|
+
scannedAt
|
|
25451
|
+
});
|
|
25452
|
+
backfillTable2(db, {
|
|
25453
|
+
table: "session_summaries",
|
|
25454
|
+
sourceKind: "summary",
|
|
25455
|
+
sourceIdColumn: "id",
|
|
25456
|
+
contentColumn: "content",
|
|
25457
|
+
scannedAt
|
|
25458
|
+
});
|
|
25459
|
+
backfillTable2(db, {
|
|
25460
|
+
table: "embeddings",
|
|
25461
|
+
sourceKind: "source_chunk",
|
|
25462
|
+
sourceIdColumn: "id",
|
|
25463
|
+
contentColumn: "chunk_text",
|
|
25464
|
+
where: "source_type IN ('source_chunk', 'source_obsidian_chunk')",
|
|
25465
|
+
scannedAt
|
|
25466
|
+
});
|
|
25467
|
+
}
|
|
25098
25468
|
var MIGRATIONS2 = [
|
|
25099
25469
|
{
|
|
25100
25470
|
version: 1,
|
|
25101
25471
|
name: "baseline",
|
|
25102
|
-
up:
|
|
25472
|
+
up: up126,
|
|
25103
25473
|
artifacts: { tables: ["memories", "conversations", "embeddings"] }
|
|
25104
25474
|
},
|
|
25105
25475
|
{
|
|
@@ -25171,7 +25541,7 @@ var MIGRATIONS2 = [
|
|
|
25171
25541
|
{
|
|
25172
25542
|
version: 12,
|
|
25173
25543
|
name: "scheduled-tasks",
|
|
25174
|
-
up:
|
|
25544
|
+
up: up127,
|
|
25175
25545
|
artifacts: { tables: ["scheduled_tasks", "task_runs"] }
|
|
25176
25546
|
},
|
|
25177
25547
|
{
|
|
@@ -26103,6 +26473,12 @@ var MIGRATIONS2 = [
|
|
|
26103
26473
|
artifacts: {
|
|
26104
26474
|
tables: ["imported_source_lifecycle"]
|
|
26105
26475
|
}
|
|
26476
|
+
},
|
|
26477
|
+
{
|
|
26478
|
+
version: 125,
|
|
26479
|
+
name: "memory-content-safety",
|
|
26480
|
+
up: up1252,
|
|
26481
|
+
artifacts: { tables: ["memory_content_safety"] }
|
|
26106
26482
|
}
|
|
26107
26483
|
];
|
|
26108
26484
|
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-openclaw",
|
|
3
|
-
"version": "0.193.
|
|
3
|
+
"version": "0.193.2",
|
|
4
4
|
"description": "Signet connector for OpenClaw - configures workspace and memory hooks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"test": "bun test"
|
|
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",
|