@signetai/connector-gemini 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
|
@@ -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;
|
|
@@ -19266,6 +19454,99 @@ var PIPELINE_PROVIDER_CHOICES2 = [
|
|
|
19266
19454
|
var SYNTHESIS_PROVIDER_CHOICES2 = PIPELINE_PROVIDER_CHOICES2.filter((provider) => provider !== "command");
|
|
19267
19455
|
var PIPELINE_PROVIDER_SET2 = new Set(PIPELINE_PROVIDER_CHOICES2);
|
|
19268
19456
|
var SYNTHESIS_PROVIDER_SET2 = new Set(SYNTHESIS_PROVIDER_CHOICES2);
|
|
19457
|
+
var MEMORY_CONTENT_SAFETY_POLICY_VERSION2 = "memory-content-safety-v1";
|
|
19458
|
+
var MEMORY_CONTENT_SAFETY_REASONS2 = [
|
|
19459
|
+
"prompt_injection",
|
|
19460
|
+
"exfiltration",
|
|
19461
|
+
"credential_harvesting",
|
|
19462
|
+
"malicious_shell",
|
|
19463
|
+
"tool_directive",
|
|
19464
|
+
"invisible_unicode"
|
|
19465
|
+
];
|
|
19466
|
+
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;
|
|
19467
|
+
var STRONG_DEFENSIVE_CONTEXT_RE2 = /\b(?:security\s+(?:guidance|discussion|analysis)|threat\s+model|defensive)\b/i;
|
|
19468
|
+
var REPORTING_CONTEXT_RE2 = /\b(?:example|illustrat\w*|sample|quote|quoted|detector|scanner|classif\w*)\b/i;
|
|
19469
|
+
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;
|
|
19470
|
+
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;
|
|
19471
|
+
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;
|
|
19472
|
+
var PROMPT_INJECTION_RES2 = [
|
|
19473
|
+
/\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,
|
|
19474
|
+
/\b(?:new|following|these)\s+(?:(?:system|developer|assistant|hidden)\s+)?instructions?\b/i,
|
|
19475
|
+
/(?:^|\n)\s*(?:system|developer|instruction|prompt)\s*:/im,
|
|
19476
|
+
/<\s*(?:system|developer|assistant|instruction|prompt)\b[^>]*>/i,
|
|
19477
|
+
/\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
|
|
19478
|
+
];
|
|
19479
|
+
var TOOL_DIRECTIVE_RES2 = [
|
|
19480
|
+
/<\s*(?:tool[_-]?call|function[_-]?call|invoke|tool)\b/i,
|
|
19481
|
+
/\b(?:assistant|system)\s+to\s*=\s*[a-z0-9_.-]+/i,
|
|
19482
|
+
/\b(?:call|invoke|use|run|execute)\s+(?:the\s+)?[a-z0-9_.-]+\s+tool\b/i
|
|
19483
|
+
];
|
|
19484
|
+
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;
|
|
19485
|
+
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;
|
|
19486
|
+
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;
|
|
19487
|
+
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;
|
|
19488
|
+
function matchHasDefensiveContext2(content, match) {
|
|
19489
|
+
if (!match || !match[0])
|
|
19490
|
+
return false;
|
|
19491
|
+
const start = match.index ?? 0;
|
|
19492
|
+
const before = content.slice(Math.max(0, start - 120), start);
|
|
19493
|
+
const after = content.slice(start + match[0].length, start + match[0].length + 160);
|
|
19494
|
+
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);
|
|
19495
|
+
}
|
|
19496
|
+
function hasActionableMatch2(content, patterns) {
|
|
19497
|
+
return patterns.some((pattern) => {
|
|
19498
|
+
const flags = pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`;
|
|
19499
|
+
const searchable = new RegExp(pattern.source, flags);
|
|
19500
|
+
let match;
|
|
19501
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
19502
|
+
if (!matchHasDefensiveContext2(content, match))
|
|
19503
|
+
return true;
|
|
19504
|
+
if (match[0].length === 0)
|
|
19505
|
+
searchable.lastIndex += 1;
|
|
19506
|
+
}
|
|
19507
|
+
return false;
|
|
19508
|
+
});
|
|
19509
|
+
}
|
|
19510
|
+
function hasDangerousShell2(content) {
|
|
19511
|
+
const searchable = new RegExp(DANGEROUS_SHELL_RE2.source, `${DANGEROUS_SHELL_RE2.flags}g`);
|
|
19512
|
+
let match;
|
|
19513
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
19514
|
+
if (matchHasDefensiveContext2(content, match))
|
|
19515
|
+
continue;
|
|
19516
|
+
const end = (match.index ?? 0) + match[0].length;
|
|
19517
|
+
const after = content.slice(end, end + 160);
|
|
19518
|
+
if (!STRONG_DEFENSIVE_CONTEXT_RE2.test(after) && !REPORTING_AFTER_RE2.test(after))
|
|
19519
|
+
return true;
|
|
19520
|
+
if (match[0].length === 0)
|
|
19521
|
+
searchable.lastIndex += 1;
|
|
19522
|
+
}
|
|
19523
|
+
return false;
|
|
19524
|
+
}
|
|
19525
|
+
function scanMemoryContent2(content) {
|
|
19526
|
+
const raw = typeof content === "string" ? content : String(content ?? "");
|
|
19527
|
+
const normalized = raw.normalize("NFKC");
|
|
19528
|
+
const reasons = new Set;
|
|
19529
|
+
if (INVISIBLE_UNICODE_RE2.test(raw))
|
|
19530
|
+
reasons.add("invisible_unicode");
|
|
19531
|
+
if (hasActionableMatch2(normalized, PROMPT_INJECTION_RES2))
|
|
19532
|
+
reasons.add("prompt_injection");
|
|
19533
|
+
if (hasActionableMatch2(normalized, TOOL_DIRECTIVE_RES2))
|
|
19534
|
+
reasons.add("tool_directive");
|
|
19535
|
+
if (hasActionableMatch2(normalized, [EXFILTRATION_RE2, EXFILTRATION_REVERSE2]))
|
|
19536
|
+
reasons.add("exfiltration");
|
|
19537
|
+
if (hasActionableMatch2(normalized, [CREDENTIAL_HARVESTING_RE2]))
|
|
19538
|
+
reasons.add("credential_harvesting");
|
|
19539
|
+
if (hasDangerousShell2(normalized))
|
|
19540
|
+
reasons.add("malicious_shell");
|
|
19541
|
+
const orderedReasons = MEMORY_CONTENT_SAFETY_REASONS2.filter((reason) => reasons.has(reason));
|
|
19542
|
+
const status = orderedReasons.length === 0 ? "clean" : orderedReasons.every((reason) => reason === "invisible_unicode") ? "tainted" : "blocked";
|
|
19543
|
+
return {
|
|
19544
|
+
status,
|
|
19545
|
+
contextEligible: status === "clean",
|
|
19546
|
+
reasons: orderedReasons,
|
|
19547
|
+
policyVersion: MEMORY_CONTENT_SAFETY_POLICY_VERSION2
|
|
19548
|
+
};
|
|
19549
|
+
}
|
|
19269
19550
|
var DAEMON_DERIVED_MEMORY_SOURCE_TYPES2 = ["extract", "aggregate-recall", "session_end", "checkpoint", "dreaming"];
|
|
19270
19551
|
var MEMORIES_FTS_TOKENIZER2 = "unicode61";
|
|
19271
19552
|
function normalizeSql2(sql) {
|
|
@@ -19317,7 +19598,7 @@ function memoriesFtsNeedsTokenizerRepair2(sql) {
|
|
|
19317
19598
|
return true;
|
|
19318
19599
|
return !normalized.includes(`tokenize='${MEMORIES_FTS_TOKENIZER2}'`);
|
|
19319
19600
|
}
|
|
19320
|
-
function
|
|
19601
|
+
function up126(db) {
|
|
19321
19602
|
db.exec(`
|
|
19322
19603
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
19323
19604
|
version INTEGER PRIMARY KEY,
|
|
@@ -19406,12 +19687,12 @@ function up125(db) {
|
|
|
19406
19687
|
} catch {}
|
|
19407
19688
|
createMemoriesFts2(db);
|
|
19408
19689
|
}
|
|
19409
|
-
function
|
|
19690
|
+
function hasColumn25(db, table, column) {
|
|
19410
19691
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
19411
19692
|
return rows.some((r) => r.name === column);
|
|
19412
19693
|
}
|
|
19413
19694
|
function addColumnIfMissing27(db, table, column, definition) {
|
|
19414
|
-
if (!
|
|
19695
|
+
if (!hasColumn25(db, table, column)) {
|
|
19415
19696
|
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
19416
19697
|
}
|
|
19417
19698
|
}
|
|
@@ -19561,12 +19842,12 @@ function up310(db) {
|
|
|
19561
19842
|
WHERE content_hash IS NOT NULL AND is_deleted = 0
|
|
19562
19843
|
`);
|
|
19563
19844
|
}
|
|
19564
|
-
function
|
|
19845
|
+
function hasColumn26(db, table, column) {
|
|
19565
19846
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
19566
19847
|
return rows.some((r) => r.name === column);
|
|
19567
19848
|
}
|
|
19568
19849
|
function addColumnIfMissing32(db, table, column, definition) {
|
|
19569
|
-
if (!
|
|
19850
|
+
if (!hasColumn26(db, table, column)) {
|
|
19570
19851
|
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
19571
19852
|
}
|
|
19572
19853
|
}
|
|
@@ -19760,7 +20041,7 @@ function up1110(db) {
|
|
|
19760
20041
|
ON session_scores(session_key);
|
|
19761
20042
|
`);
|
|
19762
20043
|
}
|
|
19763
|
-
function
|
|
20044
|
+
function up127(db) {
|
|
19764
20045
|
db.exec(`
|
|
19765
20046
|
CREATE TABLE IF NOT EXISTS scheduled_tasks (
|
|
19766
20047
|
id TEXT PRIMARY KEY,
|
|
@@ -22552,7 +22833,7 @@ function up1032(db) {
|
|
|
22552
22833
|
)
|
|
22553
22834
|
`);
|
|
22554
22835
|
}
|
|
22555
|
-
function
|
|
22836
|
+
function tableExists3(db, table) {
|
|
22556
22837
|
return db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) !== undefined;
|
|
22557
22838
|
}
|
|
22558
22839
|
function hasColumn162(db, table, column) {
|
|
@@ -22574,7 +22855,7 @@ function up1042(db) {
|
|
|
22574
22855
|
CREATE INDEX IF NOT EXISTS idx_derived_memory_sources_source
|
|
22575
22856
|
ON derived_memory_sources(agent_id, source_kind, source_id);
|
|
22576
22857
|
`);
|
|
22577
|
-
if (
|
|
22858
|
+
if (tableExists3(db, "aggregate_evidence_sources")) {
|
|
22578
22859
|
db.exec(`
|
|
22579
22860
|
INSERT OR IGNORE INTO derived_memory_sources
|
|
22580
22861
|
(derived_memory_id, source_kind, source_id, source_path, agent_id, created_at)
|
|
@@ -22582,7 +22863,7 @@ function up1042(db) {
|
|
|
22582
22863
|
FROM aggregate_evidence_sources
|
|
22583
22864
|
`);
|
|
22584
22865
|
}
|
|
22585
|
-
if (
|
|
22866
|
+
if (tableExists3(db, "aggregate_memory_sources")) {
|
|
22586
22867
|
db.exec(`
|
|
22587
22868
|
INSERT OR IGNORE INTO derived_memory_sources
|
|
22588
22869
|
(derived_memory_id, source_kind, source_id, source_path, agent_id, created_at)
|
|
@@ -22590,10 +22871,10 @@ function up1042(db) {
|
|
|
22590
22871
|
FROM aggregate_memory_sources
|
|
22591
22872
|
`);
|
|
22592
22873
|
}
|
|
22593
|
-
if (
|
|
22874
|
+
if (tableExists3(db, "memories") && !hasColumn162(db, "memories", "stale_at")) {
|
|
22594
22875
|
db.exec("ALTER TABLE memories ADD COLUMN stale_at TEXT");
|
|
22595
22876
|
}
|
|
22596
|
-
if (
|
|
22877
|
+
if (tableExists3(db, "memories")) {
|
|
22597
22878
|
db.exec(`
|
|
22598
22879
|
CREATE INDEX IF NOT EXISTS idx_memories_stale_derived
|
|
22599
22880
|
ON memories(agent_id, stale_at)
|
|
@@ -23244,11 +23525,100 @@ function up1242(db) {
|
|
|
23244
23525
|
ON imported_source_lifecycle(agent_id, status, updated_at DESC);
|
|
23245
23526
|
`);
|
|
23246
23527
|
}
|
|
23528
|
+
function tableExists22(db, table) {
|
|
23529
|
+
return db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
23530
|
+
}
|
|
23531
|
+
function hasColumn242(db, table, column) {
|
|
23532
|
+
return db.prepare(`PRAGMA table_info("${table}")`).all().some((row) => row.name === column);
|
|
23533
|
+
}
|
|
23534
|
+
function backfill2(db, rows, sourceKind, scannedAt) {
|
|
23535
|
+
const statement = db.prepare(`INSERT INTO memory_content_safety
|
|
23536
|
+
(agent_id, source_kind, source_id, status, context_eligible, reasons_json, policy_version, scanned_at)
|
|
23537
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
23538
|
+
ON CONFLICT(agent_id, source_kind, source_id) DO UPDATE SET
|
|
23539
|
+
status = excluded.status,
|
|
23540
|
+
context_eligible = excluded.context_eligible,
|
|
23541
|
+
reasons_json = excluded.reasons_json,
|
|
23542
|
+
policy_version = excluded.policy_version,
|
|
23543
|
+
scanned_at = excluded.scanned_at`);
|
|
23544
|
+
for (const row of rows) {
|
|
23545
|
+
const sourceId = row.source_id?.trim();
|
|
23546
|
+
if (!sourceId)
|
|
23547
|
+
continue;
|
|
23548
|
+
const assessment = scanMemoryContent2(row.content ?? "");
|
|
23549
|
+
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);
|
|
23550
|
+
}
|
|
23551
|
+
}
|
|
23552
|
+
function backfillTable2(db, params) {
|
|
23553
|
+
if (!tableExists22(db, params.table) || !hasColumn242(db, params.table, params.sourceIdColumn) || !hasColumn242(db, params.table, params.contentColumn))
|
|
23554
|
+
return;
|
|
23555
|
+
const agentColumn = hasColumn242(db, params.table, "agent_id") ? "COALESCE(NULLIF(TRIM(agent_id), ''), 'default')" : "'default'";
|
|
23556
|
+
const rows = db.prepare(`SELECT ${agentColumn} AS agent_id, ${params.sourceIdColumn} AS source_id, ${params.contentColumn} AS content
|
|
23557
|
+
FROM ${params.table}${params.where ? ` WHERE ${params.where}` : ""}`).all();
|
|
23558
|
+
backfill2(db, rows, params.sourceKind, params.scannedAt);
|
|
23559
|
+
}
|
|
23560
|
+
function up1252(db) {
|
|
23561
|
+
db.exec(`
|
|
23562
|
+
CREATE TABLE IF NOT EXISTS memory_content_safety (
|
|
23563
|
+
agent_id TEXT NOT NULL,
|
|
23564
|
+
source_kind TEXT NOT NULL CHECK (source_kind IN ('memory', 'artifact', 'transcript', 'summary', 'source_chunk')),
|
|
23565
|
+
source_id TEXT NOT NULL,
|
|
23566
|
+
status TEXT NOT NULL CHECK (status IN ('clean', 'tainted', 'blocked')),
|
|
23567
|
+
context_eligible INTEGER NOT NULL CHECK (context_eligible IN (0, 1)),
|
|
23568
|
+
reasons_json TEXT NOT NULL DEFAULT '[]',
|
|
23569
|
+
policy_version TEXT NOT NULL,
|
|
23570
|
+
scanned_at TEXT NOT NULL,
|
|
23571
|
+
PRIMARY KEY (agent_id, source_kind, source_id)
|
|
23572
|
+
);
|
|
23573
|
+
|
|
23574
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_status
|
|
23575
|
+
ON memory_content_safety(agent_id, status, source_kind);
|
|
23576
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_eligibility
|
|
23577
|
+
ON memory_content_safety(agent_id, source_kind, context_eligible);
|
|
23578
|
+
`);
|
|
23579
|
+
const scannedAt = new Date().toISOString();
|
|
23580
|
+
backfillTable2(db, {
|
|
23581
|
+
table: "memories",
|
|
23582
|
+
sourceKind: "memory",
|
|
23583
|
+
sourceIdColumn: "id",
|
|
23584
|
+
contentColumn: "content",
|
|
23585
|
+
scannedAt
|
|
23586
|
+
});
|
|
23587
|
+
backfillTable2(db, {
|
|
23588
|
+
table: "memory_artifacts",
|
|
23589
|
+
sourceKind: "artifact",
|
|
23590
|
+
sourceIdColumn: "source_path",
|
|
23591
|
+
contentColumn: "content",
|
|
23592
|
+
scannedAt
|
|
23593
|
+
});
|
|
23594
|
+
backfillTable2(db, {
|
|
23595
|
+
table: "session_transcripts",
|
|
23596
|
+
sourceKind: "transcript",
|
|
23597
|
+
sourceIdColumn: "session_key",
|
|
23598
|
+
contentColumn: "content",
|
|
23599
|
+
scannedAt
|
|
23600
|
+
});
|
|
23601
|
+
backfillTable2(db, {
|
|
23602
|
+
table: "session_summaries",
|
|
23603
|
+
sourceKind: "summary",
|
|
23604
|
+
sourceIdColumn: "id",
|
|
23605
|
+
contentColumn: "content",
|
|
23606
|
+
scannedAt
|
|
23607
|
+
});
|
|
23608
|
+
backfillTable2(db, {
|
|
23609
|
+
table: "embeddings",
|
|
23610
|
+
sourceKind: "source_chunk",
|
|
23611
|
+
sourceIdColumn: "id",
|
|
23612
|
+
contentColumn: "chunk_text",
|
|
23613
|
+
where: "source_type IN ('source_chunk', 'source_obsidian_chunk')",
|
|
23614
|
+
scannedAt
|
|
23615
|
+
});
|
|
23616
|
+
}
|
|
23247
23617
|
var MIGRATIONS2 = [
|
|
23248
23618
|
{
|
|
23249
23619
|
version: 1,
|
|
23250
23620
|
name: "baseline",
|
|
23251
|
-
up:
|
|
23621
|
+
up: up126,
|
|
23252
23622
|
artifacts: { tables: ["memories", "conversations", "embeddings"] }
|
|
23253
23623
|
},
|
|
23254
23624
|
{
|
|
@@ -23320,7 +23690,7 @@ var MIGRATIONS2 = [
|
|
|
23320
23690
|
{
|
|
23321
23691
|
version: 12,
|
|
23322
23692
|
name: "scheduled-tasks",
|
|
23323
|
-
up:
|
|
23693
|
+
up: up127,
|
|
23324
23694
|
artifacts: { tables: ["scheduled_tasks", "task_runs"] }
|
|
23325
23695
|
},
|
|
23326
23696
|
{
|
|
@@ -24252,6 +24622,12 @@ var MIGRATIONS2 = [
|
|
|
24252
24622
|
artifacts: {
|
|
24253
24623
|
tables: ["imported_source_lifecycle"]
|
|
24254
24624
|
}
|
|
24625
|
+
},
|
|
24626
|
+
{
|
|
24627
|
+
version: 125,
|
|
24628
|
+
name: "memory-content-safety",
|
|
24629
|
+
up: up1252,
|
|
24630
|
+
artifacts: { tables: ["memory_content_safety"] }
|
|
24255
24631
|
}
|
|
24256
24632
|
];
|
|
24257
24633
|
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-gemini",
|
|
3
|
-
"version": "0.193.
|
|
3
|
+
"version": "0.193.2",
|
|
4
4
|
"description": "Signet connector for Gemini CLI",
|
|
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",
|