@signetai/connector-forge 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
|
@@ -6931,6 +6931,99 @@ var PIPELINE_PROVIDER_CHOICES = [
|
|
|
6931
6931
|
var SYNTHESIS_PROVIDER_CHOICES = PIPELINE_PROVIDER_CHOICES.filter((provider) => provider !== "command");
|
|
6932
6932
|
var PIPELINE_PROVIDER_SET = new Set(PIPELINE_PROVIDER_CHOICES);
|
|
6933
6933
|
var SYNTHESIS_PROVIDER_SET = new Set(SYNTHESIS_PROVIDER_CHOICES);
|
|
6934
|
+
var MEMORY_CONTENT_SAFETY_POLICY_VERSION = "memory-content-safety-v1";
|
|
6935
|
+
var MEMORY_CONTENT_SAFETY_REASONS = [
|
|
6936
|
+
"prompt_injection",
|
|
6937
|
+
"exfiltration",
|
|
6938
|
+
"credential_harvesting",
|
|
6939
|
+
"malicious_shell",
|
|
6940
|
+
"tool_directive",
|
|
6941
|
+
"invisible_unicode"
|
|
6942
|
+
];
|
|
6943
|
+
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;
|
|
6944
|
+
var STRONG_DEFENSIVE_CONTEXT_RE = /\b(?:security\s+(?:guidance|discussion|analysis)|threat\s+model|defensive)\b/i;
|
|
6945
|
+
var REPORTING_CONTEXT_RE = /\b(?:example|illustrat\w*|sample|quote|quoted|detector|scanner|classif\w*)\b/i;
|
|
6946
|
+
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;
|
|
6947
|
+
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;
|
|
6948
|
+
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;
|
|
6949
|
+
var PROMPT_INJECTION_RES = [
|
|
6950
|
+
/\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,
|
|
6951
|
+
/\b(?:new|following|these)\s+(?:(?:system|developer|assistant|hidden)\s+)?instructions?\b/i,
|
|
6952
|
+
/(?:^|\n)\s*(?:system|developer|instruction|prompt)\s*:/im,
|
|
6953
|
+
/<\s*(?:system|developer|assistant|instruction|prompt)\b[^>]*>/i,
|
|
6954
|
+
/\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
|
|
6955
|
+
];
|
|
6956
|
+
var TOOL_DIRECTIVE_RES = [
|
|
6957
|
+
/<\s*(?:tool[_-]?call|function[_-]?call|invoke|tool)\b/i,
|
|
6958
|
+
/\b(?:assistant|system)\s+to\s*=\s*[a-z0-9_.-]+/i,
|
|
6959
|
+
/\b(?:call|invoke|use|run|execute)\s+(?:the\s+)?[a-z0-9_.-]+\s+tool\b/i
|
|
6960
|
+
];
|
|
6961
|
+
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;
|
|
6962
|
+
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;
|
|
6963
|
+
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;
|
|
6964
|
+
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;
|
|
6965
|
+
function matchHasDefensiveContext(content, match) {
|
|
6966
|
+
if (!match || !match[0])
|
|
6967
|
+
return false;
|
|
6968
|
+
const start = match.index ?? 0;
|
|
6969
|
+
const before = content.slice(Math.max(0, start - 120), start);
|
|
6970
|
+
const after = content.slice(start + match[0].length, start + match[0].length + 160);
|
|
6971
|
+
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);
|
|
6972
|
+
}
|
|
6973
|
+
function hasActionableMatch(content, patterns) {
|
|
6974
|
+
return patterns.some((pattern) => {
|
|
6975
|
+
const flags = pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`;
|
|
6976
|
+
const searchable = new RegExp(pattern.source, flags);
|
|
6977
|
+
let match;
|
|
6978
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
6979
|
+
if (!matchHasDefensiveContext(content, match))
|
|
6980
|
+
return true;
|
|
6981
|
+
if (match[0].length === 0)
|
|
6982
|
+
searchable.lastIndex += 1;
|
|
6983
|
+
}
|
|
6984
|
+
return false;
|
|
6985
|
+
});
|
|
6986
|
+
}
|
|
6987
|
+
function hasDangerousShell(content) {
|
|
6988
|
+
const searchable = new RegExp(DANGEROUS_SHELL_RE.source, `${DANGEROUS_SHELL_RE.flags}g`);
|
|
6989
|
+
let match;
|
|
6990
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
6991
|
+
if (matchHasDefensiveContext(content, match))
|
|
6992
|
+
continue;
|
|
6993
|
+
const end = (match.index ?? 0) + match[0].length;
|
|
6994
|
+
const after = content.slice(end, end + 160);
|
|
6995
|
+
if (!STRONG_DEFENSIVE_CONTEXT_RE.test(after) && !REPORTING_AFTER_RE.test(after))
|
|
6996
|
+
return true;
|
|
6997
|
+
if (match[0].length === 0)
|
|
6998
|
+
searchable.lastIndex += 1;
|
|
6999
|
+
}
|
|
7000
|
+
return false;
|
|
7001
|
+
}
|
|
7002
|
+
function scanMemoryContent(content) {
|
|
7003
|
+
const raw = typeof content === "string" ? content : String(content ?? "");
|
|
7004
|
+
const normalized = raw.normalize("NFKC");
|
|
7005
|
+
const reasons = new Set;
|
|
7006
|
+
if (INVISIBLE_UNICODE_RE.test(raw))
|
|
7007
|
+
reasons.add("invisible_unicode");
|
|
7008
|
+
if (hasActionableMatch(normalized, PROMPT_INJECTION_RES))
|
|
7009
|
+
reasons.add("prompt_injection");
|
|
7010
|
+
if (hasActionableMatch(normalized, TOOL_DIRECTIVE_RES))
|
|
7011
|
+
reasons.add("tool_directive");
|
|
7012
|
+
if (hasActionableMatch(normalized, [EXFILTRATION_RE, EXFILTRATION_REVERSE]))
|
|
7013
|
+
reasons.add("exfiltration");
|
|
7014
|
+
if (hasActionableMatch(normalized, [CREDENTIAL_HARVESTING_RE]))
|
|
7015
|
+
reasons.add("credential_harvesting");
|
|
7016
|
+
if (hasDangerousShell(normalized))
|
|
7017
|
+
reasons.add("malicious_shell");
|
|
7018
|
+
const orderedReasons = MEMORY_CONTENT_SAFETY_REASONS.filter((reason) => reasons.has(reason));
|
|
7019
|
+
const status = orderedReasons.length === 0 ? "clean" : orderedReasons.every((reason) => reason === "invisible_unicode") ? "tainted" : "blocked";
|
|
7020
|
+
return {
|
|
7021
|
+
status,
|
|
7022
|
+
contextEligible: status === "clean",
|
|
7023
|
+
reasons: orderedReasons,
|
|
7024
|
+
policyVersion: MEMORY_CONTENT_SAFETY_POLICY_VERSION
|
|
7025
|
+
};
|
|
7026
|
+
}
|
|
6934
7027
|
var DAEMON_DERIVED_MEMORY_SOURCE_TYPES = ["extract", "aggregate-recall", "session_end", "checkpoint", "dreaming"];
|
|
6935
7028
|
var MEMORIES_FTS_TOKENIZER = "unicode61";
|
|
6936
7029
|
function normalizeSql(sql) {
|
|
@@ -10909,6 +11002,95 @@ function up124(db) {
|
|
|
10909
11002
|
ON imported_source_lifecycle(agent_id, status, updated_at DESC);
|
|
10910
11003
|
`);
|
|
10911
11004
|
}
|
|
11005
|
+
function tableExists2(db, table) {
|
|
11006
|
+
return db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
11007
|
+
}
|
|
11008
|
+
function hasColumn24(db, table, column) {
|
|
11009
|
+
return db.prepare(`PRAGMA table_info("${table}")`).all().some((row) => row.name === column);
|
|
11010
|
+
}
|
|
11011
|
+
function backfill(db, rows, sourceKind, scannedAt) {
|
|
11012
|
+
const statement = db.prepare(`INSERT INTO memory_content_safety
|
|
11013
|
+
(agent_id, source_kind, source_id, status, context_eligible, reasons_json, policy_version, scanned_at)
|
|
11014
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
11015
|
+
ON CONFLICT(agent_id, source_kind, source_id) DO UPDATE SET
|
|
11016
|
+
status = excluded.status,
|
|
11017
|
+
context_eligible = excluded.context_eligible,
|
|
11018
|
+
reasons_json = excluded.reasons_json,
|
|
11019
|
+
policy_version = excluded.policy_version,
|
|
11020
|
+
scanned_at = excluded.scanned_at`);
|
|
11021
|
+
for (const row of rows) {
|
|
11022
|
+
const sourceId = row.source_id?.trim();
|
|
11023
|
+
if (!sourceId)
|
|
11024
|
+
continue;
|
|
11025
|
+
const assessment = scanMemoryContent(row.content ?? "");
|
|
11026
|
+
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);
|
|
11027
|
+
}
|
|
11028
|
+
}
|
|
11029
|
+
function backfillTable(db, params) {
|
|
11030
|
+
if (!tableExists2(db, params.table) || !hasColumn24(db, params.table, params.sourceIdColumn) || !hasColumn24(db, params.table, params.contentColumn))
|
|
11031
|
+
return;
|
|
11032
|
+
const agentColumn = hasColumn24(db, params.table, "agent_id") ? "COALESCE(NULLIF(TRIM(agent_id), ''), 'default')" : "'default'";
|
|
11033
|
+
const rows = db.prepare(`SELECT ${agentColumn} AS agent_id, ${params.sourceIdColumn} AS source_id, ${params.contentColumn} AS content
|
|
11034
|
+
FROM ${params.table}${params.where ? ` WHERE ${params.where}` : ""}`).all();
|
|
11035
|
+
backfill(db, rows, params.sourceKind, params.scannedAt);
|
|
11036
|
+
}
|
|
11037
|
+
function up125(db) {
|
|
11038
|
+
db.exec(`
|
|
11039
|
+
CREATE TABLE IF NOT EXISTS memory_content_safety (
|
|
11040
|
+
agent_id TEXT NOT NULL,
|
|
11041
|
+
source_kind TEXT NOT NULL CHECK (source_kind IN ('memory', 'artifact', 'transcript', 'summary', 'source_chunk')),
|
|
11042
|
+
source_id TEXT NOT NULL,
|
|
11043
|
+
status TEXT NOT NULL CHECK (status IN ('clean', 'tainted', 'blocked')),
|
|
11044
|
+
context_eligible INTEGER NOT NULL CHECK (context_eligible IN (0, 1)),
|
|
11045
|
+
reasons_json TEXT NOT NULL DEFAULT '[]',
|
|
11046
|
+
policy_version TEXT NOT NULL,
|
|
11047
|
+
scanned_at TEXT NOT NULL,
|
|
11048
|
+
PRIMARY KEY (agent_id, source_kind, source_id)
|
|
11049
|
+
);
|
|
11050
|
+
|
|
11051
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_status
|
|
11052
|
+
ON memory_content_safety(agent_id, status, source_kind);
|
|
11053
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_eligibility
|
|
11054
|
+
ON memory_content_safety(agent_id, source_kind, context_eligible);
|
|
11055
|
+
`);
|
|
11056
|
+
const scannedAt = new Date().toISOString();
|
|
11057
|
+
backfillTable(db, {
|
|
11058
|
+
table: "memories",
|
|
11059
|
+
sourceKind: "memory",
|
|
11060
|
+
sourceIdColumn: "id",
|
|
11061
|
+
contentColumn: "content",
|
|
11062
|
+
scannedAt
|
|
11063
|
+
});
|
|
11064
|
+
backfillTable(db, {
|
|
11065
|
+
table: "memory_artifacts",
|
|
11066
|
+
sourceKind: "artifact",
|
|
11067
|
+
sourceIdColumn: "source_path",
|
|
11068
|
+
contentColumn: "content",
|
|
11069
|
+
scannedAt
|
|
11070
|
+
});
|
|
11071
|
+
backfillTable(db, {
|
|
11072
|
+
table: "session_transcripts",
|
|
11073
|
+
sourceKind: "transcript",
|
|
11074
|
+
sourceIdColumn: "session_key",
|
|
11075
|
+
contentColumn: "content",
|
|
11076
|
+
scannedAt
|
|
11077
|
+
});
|
|
11078
|
+
backfillTable(db, {
|
|
11079
|
+
table: "session_summaries",
|
|
11080
|
+
sourceKind: "summary",
|
|
11081
|
+
sourceIdColumn: "id",
|
|
11082
|
+
contentColumn: "content",
|
|
11083
|
+
scannedAt
|
|
11084
|
+
});
|
|
11085
|
+
backfillTable(db, {
|
|
11086
|
+
table: "embeddings",
|
|
11087
|
+
sourceKind: "source_chunk",
|
|
11088
|
+
sourceIdColumn: "id",
|
|
11089
|
+
contentColumn: "chunk_text",
|
|
11090
|
+
where: "source_type IN ('source_chunk', 'source_obsidian_chunk')",
|
|
11091
|
+
scannedAt
|
|
11092
|
+
});
|
|
11093
|
+
}
|
|
10912
11094
|
var MIGRATIONS = [
|
|
10913
11095
|
{
|
|
10914
11096
|
version: 1,
|
|
@@ -11917,6 +12099,12 @@ var MIGRATIONS = [
|
|
|
11917
12099
|
artifacts: {
|
|
11918
12100
|
tables: ["imported_source_lifecycle"]
|
|
11919
12101
|
}
|
|
12102
|
+
},
|
|
12103
|
+
{
|
|
12104
|
+
version: 125,
|
|
12105
|
+
name: "memory-content-safety",
|
|
12106
|
+
up: up125,
|
|
12107
|
+
artifacts: { tables: ["memory_content_safety"] }
|
|
11920
12108
|
}
|
|
11921
12109
|
];
|
|
11922
12110
|
var LATEST_SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0;
|
|
@@ -19388,6 +19576,99 @@ var PIPELINE_PROVIDER_CHOICES2 = [
|
|
|
19388
19576
|
var SYNTHESIS_PROVIDER_CHOICES2 = PIPELINE_PROVIDER_CHOICES2.filter((provider) => provider !== "command");
|
|
19389
19577
|
var PIPELINE_PROVIDER_SET2 = new Set(PIPELINE_PROVIDER_CHOICES2);
|
|
19390
19578
|
var SYNTHESIS_PROVIDER_SET2 = new Set(SYNTHESIS_PROVIDER_CHOICES2);
|
|
19579
|
+
var MEMORY_CONTENT_SAFETY_POLICY_VERSION2 = "memory-content-safety-v1";
|
|
19580
|
+
var MEMORY_CONTENT_SAFETY_REASONS2 = [
|
|
19581
|
+
"prompt_injection",
|
|
19582
|
+
"exfiltration",
|
|
19583
|
+
"credential_harvesting",
|
|
19584
|
+
"malicious_shell",
|
|
19585
|
+
"tool_directive",
|
|
19586
|
+
"invisible_unicode"
|
|
19587
|
+
];
|
|
19588
|
+
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;
|
|
19589
|
+
var STRONG_DEFENSIVE_CONTEXT_RE2 = /\b(?:security\s+(?:guidance|discussion|analysis)|threat\s+model|defensive)\b/i;
|
|
19590
|
+
var REPORTING_CONTEXT_RE2 = /\b(?:example|illustrat\w*|sample|quote|quoted|detector|scanner|classif\w*)\b/i;
|
|
19591
|
+
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;
|
|
19592
|
+
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;
|
|
19593
|
+
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;
|
|
19594
|
+
var PROMPT_INJECTION_RES2 = [
|
|
19595
|
+
/\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,
|
|
19596
|
+
/\b(?:new|following|these)\s+(?:(?:system|developer|assistant|hidden)\s+)?instructions?\b/i,
|
|
19597
|
+
/(?:^|\n)\s*(?:system|developer|instruction|prompt)\s*:/im,
|
|
19598
|
+
/<\s*(?:system|developer|assistant|instruction|prompt)\b[^>]*>/i,
|
|
19599
|
+
/\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
|
|
19600
|
+
];
|
|
19601
|
+
var TOOL_DIRECTIVE_RES2 = [
|
|
19602
|
+
/<\s*(?:tool[_-]?call|function[_-]?call|invoke|tool)\b/i,
|
|
19603
|
+
/\b(?:assistant|system)\s+to\s*=\s*[a-z0-9_.-]+/i,
|
|
19604
|
+
/\b(?:call|invoke|use|run|execute)\s+(?:the\s+)?[a-z0-9_.-]+\s+tool\b/i
|
|
19605
|
+
];
|
|
19606
|
+
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;
|
|
19607
|
+
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;
|
|
19608
|
+
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;
|
|
19609
|
+
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;
|
|
19610
|
+
function matchHasDefensiveContext2(content, match) {
|
|
19611
|
+
if (!match || !match[0])
|
|
19612
|
+
return false;
|
|
19613
|
+
const start = match.index ?? 0;
|
|
19614
|
+
const before = content.slice(Math.max(0, start - 120), start);
|
|
19615
|
+
const after = content.slice(start + match[0].length, start + match[0].length + 160);
|
|
19616
|
+
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);
|
|
19617
|
+
}
|
|
19618
|
+
function hasActionableMatch2(content, patterns) {
|
|
19619
|
+
return patterns.some((pattern) => {
|
|
19620
|
+
const flags = pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`;
|
|
19621
|
+
const searchable = new RegExp(pattern.source, flags);
|
|
19622
|
+
let match;
|
|
19623
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
19624
|
+
if (!matchHasDefensiveContext2(content, match))
|
|
19625
|
+
return true;
|
|
19626
|
+
if (match[0].length === 0)
|
|
19627
|
+
searchable.lastIndex += 1;
|
|
19628
|
+
}
|
|
19629
|
+
return false;
|
|
19630
|
+
});
|
|
19631
|
+
}
|
|
19632
|
+
function hasDangerousShell2(content) {
|
|
19633
|
+
const searchable = new RegExp(DANGEROUS_SHELL_RE2.source, `${DANGEROUS_SHELL_RE2.flags}g`);
|
|
19634
|
+
let match;
|
|
19635
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
19636
|
+
if (matchHasDefensiveContext2(content, match))
|
|
19637
|
+
continue;
|
|
19638
|
+
const end = (match.index ?? 0) + match[0].length;
|
|
19639
|
+
const after = content.slice(end, end + 160);
|
|
19640
|
+
if (!STRONG_DEFENSIVE_CONTEXT_RE2.test(after) && !REPORTING_AFTER_RE2.test(after))
|
|
19641
|
+
return true;
|
|
19642
|
+
if (match[0].length === 0)
|
|
19643
|
+
searchable.lastIndex += 1;
|
|
19644
|
+
}
|
|
19645
|
+
return false;
|
|
19646
|
+
}
|
|
19647
|
+
function scanMemoryContent2(content) {
|
|
19648
|
+
const raw = typeof content === "string" ? content : String(content ?? "");
|
|
19649
|
+
const normalized = raw.normalize("NFKC");
|
|
19650
|
+
const reasons = new Set;
|
|
19651
|
+
if (INVISIBLE_UNICODE_RE2.test(raw))
|
|
19652
|
+
reasons.add("invisible_unicode");
|
|
19653
|
+
if (hasActionableMatch2(normalized, PROMPT_INJECTION_RES2))
|
|
19654
|
+
reasons.add("prompt_injection");
|
|
19655
|
+
if (hasActionableMatch2(normalized, TOOL_DIRECTIVE_RES2))
|
|
19656
|
+
reasons.add("tool_directive");
|
|
19657
|
+
if (hasActionableMatch2(normalized, [EXFILTRATION_RE2, EXFILTRATION_REVERSE2]))
|
|
19658
|
+
reasons.add("exfiltration");
|
|
19659
|
+
if (hasActionableMatch2(normalized, [CREDENTIAL_HARVESTING_RE2]))
|
|
19660
|
+
reasons.add("credential_harvesting");
|
|
19661
|
+
if (hasDangerousShell2(normalized))
|
|
19662
|
+
reasons.add("malicious_shell");
|
|
19663
|
+
const orderedReasons = MEMORY_CONTENT_SAFETY_REASONS2.filter((reason) => reasons.has(reason));
|
|
19664
|
+
const status = orderedReasons.length === 0 ? "clean" : orderedReasons.every((reason) => reason === "invisible_unicode") ? "tainted" : "blocked";
|
|
19665
|
+
return {
|
|
19666
|
+
status,
|
|
19667
|
+
contextEligible: status === "clean",
|
|
19668
|
+
reasons: orderedReasons,
|
|
19669
|
+
policyVersion: MEMORY_CONTENT_SAFETY_POLICY_VERSION2
|
|
19670
|
+
};
|
|
19671
|
+
}
|
|
19391
19672
|
var DAEMON_DERIVED_MEMORY_SOURCE_TYPES2 = ["extract", "aggregate-recall", "session_end", "checkpoint", "dreaming"];
|
|
19392
19673
|
var MEMORIES_FTS_TOKENIZER2 = "unicode61";
|
|
19393
19674
|
function normalizeSql2(sql) {
|
|
@@ -19439,7 +19720,7 @@ function memoriesFtsNeedsTokenizerRepair2(sql) {
|
|
|
19439
19720
|
return true;
|
|
19440
19721
|
return !normalized.includes(`tokenize='${MEMORIES_FTS_TOKENIZER2}'`);
|
|
19441
19722
|
}
|
|
19442
|
-
function
|
|
19723
|
+
function up126(db) {
|
|
19443
19724
|
db.exec(`
|
|
19444
19725
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
19445
19726
|
version INTEGER PRIMARY KEY,
|
|
@@ -19528,12 +19809,12 @@ function up125(db) {
|
|
|
19528
19809
|
} catch {}
|
|
19529
19810
|
createMemoriesFts2(db);
|
|
19530
19811
|
}
|
|
19531
|
-
function
|
|
19812
|
+
function hasColumn25(db, table, column) {
|
|
19532
19813
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
19533
19814
|
return rows.some((r) => r.name === column);
|
|
19534
19815
|
}
|
|
19535
19816
|
function addColumnIfMissing27(db, table, column, definition) {
|
|
19536
|
-
if (!
|
|
19817
|
+
if (!hasColumn25(db, table, column)) {
|
|
19537
19818
|
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
19538
19819
|
}
|
|
19539
19820
|
}
|
|
@@ -19683,12 +19964,12 @@ function up310(db) {
|
|
|
19683
19964
|
WHERE content_hash IS NOT NULL AND is_deleted = 0
|
|
19684
19965
|
`);
|
|
19685
19966
|
}
|
|
19686
|
-
function
|
|
19967
|
+
function hasColumn26(db, table, column) {
|
|
19687
19968
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
19688
19969
|
return rows.some((r) => r.name === column);
|
|
19689
19970
|
}
|
|
19690
19971
|
function addColumnIfMissing32(db, table, column, definition) {
|
|
19691
|
-
if (!
|
|
19972
|
+
if (!hasColumn26(db, table, column)) {
|
|
19692
19973
|
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
19693
19974
|
}
|
|
19694
19975
|
}
|
|
@@ -19882,7 +20163,7 @@ function up1110(db) {
|
|
|
19882
20163
|
ON session_scores(session_key);
|
|
19883
20164
|
`);
|
|
19884
20165
|
}
|
|
19885
|
-
function
|
|
20166
|
+
function up127(db) {
|
|
19886
20167
|
db.exec(`
|
|
19887
20168
|
CREATE TABLE IF NOT EXISTS scheduled_tasks (
|
|
19888
20169
|
id TEXT PRIMARY KEY,
|
|
@@ -22674,7 +22955,7 @@ function up1032(db) {
|
|
|
22674
22955
|
)
|
|
22675
22956
|
`);
|
|
22676
22957
|
}
|
|
22677
|
-
function
|
|
22958
|
+
function tableExists3(db, table) {
|
|
22678
22959
|
return db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) !== undefined;
|
|
22679
22960
|
}
|
|
22680
22961
|
function hasColumn162(db, table, column) {
|
|
@@ -22696,7 +22977,7 @@ function up1042(db) {
|
|
|
22696
22977
|
CREATE INDEX IF NOT EXISTS idx_derived_memory_sources_source
|
|
22697
22978
|
ON derived_memory_sources(agent_id, source_kind, source_id);
|
|
22698
22979
|
`);
|
|
22699
|
-
if (
|
|
22980
|
+
if (tableExists3(db, "aggregate_evidence_sources")) {
|
|
22700
22981
|
db.exec(`
|
|
22701
22982
|
INSERT OR IGNORE INTO derived_memory_sources
|
|
22702
22983
|
(derived_memory_id, source_kind, source_id, source_path, agent_id, created_at)
|
|
@@ -22704,7 +22985,7 @@ function up1042(db) {
|
|
|
22704
22985
|
FROM aggregate_evidence_sources
|
|
22705
22986
|
`);
|
|
22706
22987
|
}
|
|
22707
|
-
if (
|
|
22988
|
+
if (tableExists3(db, "aggregate_memory_sources")) {
|
|
22708
22989
|
db.exec(`
|
|
22709
22990
|
INSERT OR IGNORE INTO derived_memory_sources
|
|
22710
22991
|
(derived_memory_id, source_kind, source_id, source_path, agent_id, created_at)
|
|
@@ -22712,10 +22993,10 @@ function up1042(db) {
|
|
|
22712
22993
|
FROM aggregate_memory_sources
|
|
22713
22994
|
`);
|
|
22714
22995
|
}
|
|
22715
|
-
if (
|
|
22996
|
+
if (tableExists3(db, "memories") && !hasColumn162(db, "memories", "stale_at")) {
|
|
22716
22997
|
db.exec("ALTER TABLE memories ADD COLUMN stale_at TEXT");
|
|
22717
22998
|
}
|
|
22718
|
-
if (
|
|
22999
|
+
if (tableExists3(db, "memories")) {
|
|
22719
23000
|
db.exec(`
|
|
22720
23001
|
CREATE INDEX IF NOT EXISTS idx_memories_stale_derived
|
|
22721
23002
|
ON memories(agent_id, stale_at)
|
|
@@ -23366,11 +23647,100 @@ function up1242(db) {
|
|
|
23366
23647
|
ON imported_source_lifecycle(agent_id, status, updated_at DESC);
|
|
23367
23648
|
`);
|
|
23368
23649
|
}
|
|
23650
|
+
function tableExists22(db, table) {
|
|
23651
|
+
return db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
23652
|
+
}
|
|
23653
|
+
function hasColumn242(db, table, column) {
|
|
23654
|
+
return db.prepare(`PRAGMA table_info("${table}")`).all().some((row) => row.name === column);
|
|
23655
|
+
}
|
|
23656
|
+
function backfill2(db, rows, sourceKind, scannedAt) {
|
|
23657
|
+
const statement = db.prepare(`INSERT INTO memory_content_safety
|
|
23658
|
+
(agent_id, source_kind, source_id, status, context_eligible, reasons_json, policy_version, scanned_at)
|
|
23659
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
23660
|
+
ON CONFLICT(agent_id, source_kind, source_id) DO UPDATE SET
|
|
23661
|
+
status = excluded.status,
|
|
23662
|
+
context_eligible = excluded.context_eligible,
|
|
23663
|
+
reasons_json = excluded.reasons_json,
|
|
23664
|
+
policy_version = excluded.policy_version,
|
|
23665
|
+
scanned_at = excluded.scanned_at`);
|
|
23666
|
+
for (const row of rows) {
|
|
23667
|
+
const sourceId = row.source_id?.trim();
|
|
23668
|
+
if (!sourceId)
|
|
23669
|
+
continue;
|
|
23670
|
+
const assessment = scanMemoryContent2(row.content ?? "");
|
|
23671
|
+
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);
|
|
23672
|
+
}
|
|
23673
|
+
}
|
|
23674
|
+
function backfillTable2(db, params) {
|
|
23675
|
+
if (!tableExists22(db, params.table) || !hasColumn242(db, params.table, params.sourceIdColumn) || !hasColumn242(db, params.table, params.contentColumn))
|
|
23676
|
+
return;
|
|
23677
|
+
const agentColumn = hasColumn242(db, params.table, "agent_id") ? "COALESCE(NULLIF(TRIM(agent_id), ''), 'default')" : "'default'";
|
|
23678
|
+
const rows = db.prepare(`SELECT ${agentColumn} AS agent_id, ${params.sourceIdColumn} AS source_id, ${params.contentColumn} AS content
|
|
23679
|
+
FROM ${params.table}${params.where ? ` WHERE ${params.where}` : ""}`).all();
|
|
23680
|
+
backfill2(db, rows, params.sourceKind, params.scannedAt);
|
|
23681
|
+
}
|
|
23682
|
+
function up1252(db) {
|
|
23683
|
+
db.exec(`
|
|
23684
|
+
CREATE TABLE IF NOT EXISTS memory_content_safety (
|
|
23685
|
+
agent_id TEXT NOT NULL,
|
|
23686
|
+
source_kind TEXT NOT NULL CHECK (source_kind IN ('memory', 'artifact', 'transcript', 'summary', 'source_chunk')),
|
|
23687
|
+
source_id TEXT NOT NULL,
|
|
23688
|
+
status TEXT NOT NULL CHECK (status IN ('clean', 'tainted', 'blocked')),
|
|
23689
|
+
context_eligible INTEGER NOT NULL CHECK (context_eligible IN (0, 1)),
|
|
23690
|
+
reasons_json TEXT NOT NULL DEFAULT '[]',
|
|
23691
|
+
policy_version TEXT NOT NULL,
|
|
23692
|
+
scanned_at TEXT NOT NULL,
|
|
23693
|
+
PRIMARY KEY (agent_id, source_kind, source_id)
|
|
23694
|
+
);
|
|
23695
|
+
|
|
23696
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_status
|
|
23697
|
+
ON memory_content_safety(agent_id, status, source_kind);
|
|
23698
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_eligibility
|
|
23699
|
+
ON memory_content_safety(agent_id, source_kind, context_eligible);
|
|
23700
|
+
`);
|
|
23701
|
+
const scannedAt = new Date().toISOString();
|
|
23702
|
+
backfillTable2(db, {
|
|
23703
|
+
table: "memories",
|
|
23704
|
+
sourceKind: "memory",
|
|
23705
|
+
sourceIdColumn: "id",
|
|
23706
|
+
contentColumn: "content",
|
|
23707
|
+
scannedAt
|
|
23708
|
+
});
|
|
23709
|
+
backfillTable2(db, {
|
|
23710
|
+
table: "memory_artifacts",
|
|
23711
|
+
sourceKind: "artifact",
|
|
23712
|
+
sourceIdColumn: "source_path",
|
|
23713
|
+
contentColumn: "content",
|
|
23714
|
+
scannedAt
|
|
23715
|
+
});
|
|
23716
|
+
backfillTable2(db, {
|
|
23717
|
+
table: "session_transcripts",
|
|
23718
|
+
sourceKind: "transcript",
|
|
23719
|
+
sourceIdColumn: "session_key",
|
|
23720
|
+
contentColumn: "content",
|
|
23721
|
+
scannedAt
|
|
23722
|
+
});
|
|
23723
|
+
backfillTable2(db, {
|
|
23724
|
+
table: "session_summaries",
|
|
23725
|
+
sourceKind: "summary",
|
|
23726
|
+
sourceIdColumn: "id",
|
|
23727
|
+
contentColumn: "content",
|
|
23728
|
+
scannedAt
|
|
23729
|
+
});
|
|
23730
|
+
backfillTable2(db, {
|
|
23731
|
+
table: "embeddings",
|
|
23732
|
+
sourceKind: "source_chunk",
|
|
23733
|
+
sourceIdColumn: "id",
|
|
23734
|
+
contentColumn: "chunk_text",
|
|
23735
|
+
where: "source_type IN ('source_chunk', 'source_obsidian_chunk')",
|
|
23736
|
+
scannedAt
|
|
23737
|
+
});
|
|
23738
|
+
}
|
|
23369
23739
|
var MIGRATIONS2 = [
|
|
23370
23740
|
{
|
|
23371
23741
|
version: 1,
|
|
23372
23742
|
name: "baseline",
|
|
23373
|
-
up:
|
|
23743
|
+
up: up126,
|
|
23374
23744
|
artifacts: { tables: ["memories", "conversations", "embeddings"] }
|
|
23375
23745
|
},
|
|
23376
23746
|
{
|
|
@@ -23442,7 +23812,7 @@ var MIGRATIONS2 = [
|
|
|
23442
23812
|
{
|
|
23443
23813
|
version: 12,
|
|
23444
23814
|
name: "scheduled-tasks",
|
|
23445
|
-
up:
|
|
23815
|
+
up: up127,
|
|
23446
23816
|
artifacts: { tables: ["scheduled_tasks", "task_runs"] }
|
|
23447
23817
|
},
|
|
23448
23818
|
{
|
|
@@ -24374,6 +24744,12 @@ var MIGRATIONS2 = [
|
|
|
24374
24744
|
artifacts: {
|
|
24375
24745
|
tables: ["imported_source_lifecycle"]
|
|
24376
24746
|
}
|
|
24747
|
+
},
|
|
24748
|
+
{
|
|
24749
|
+
version: 125,
|
|
24750
|
+
name: "memory-content-safety",
|
|
24751
|
+
up: up1252,
|
|
24752
|
+
artifacts: { tables: ["memory_content_safety"] }
|
|
24377
24753
|
}
|
|
24378
24754
|
];
|
|
24379
24755
|
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-forge",
|
|
3
|
-
"version": "0.193.
|
|
3
|
+
"version": "0.193.2",
|
|
4
4
|
"description": "Signet connector for ForgeCode - installs MCP, identity, and skills integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"typecheck": "tsc --noEmit"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@signetai/connector-base": "0.193.
|
|
28
|
-
"@signetai/core": "0.193.
|
|
27
|
+
"@signetai/connector-base": "0.193.2",
|
|
28
|
+
"@signetai/core": "0.193.2"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^22.0.0",
|