@signetai/connector-base 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 +188 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -6950,6 +6950,99 @@ var PIPELINE_PROVIDER_CHOICES = [
|
|
|
6950
6950
|
var SYNTHESIS_PROVIDER_CHOICES = PIPELINE_PROVIDER_CHOICES.filter((provider) => provider !== "command");
|
|
6951
6951
|
var PIPELINE_PROVIDER_SET = new Set(PIPELINE_PROVIDER_CHOICES);
|
|
6952
6952
|
var SYNTHESIS_PROVIDER_SET = new Set(SYNTHESIS_PROVIDER_CHOICES);
|
|
6953
|
+
var MEMORY_CONTENT_SAFETY_POLICY_VERSION = "memory-content-safety-v1";
|
|
6954
|
+
var MEMORY_CONTENT_SAFETY_REASONS = [
|
|
6955
|
+
"prompt_injection",
|
|
6956
|
+
"exfiltration",
|
|
6957
|
+
"credential_harvesting",
|
|
6958
|
+
"malicious_shell",
|
|
6959
|
+
"tool_directive",
|
|
6960
|
+
"invisible_unicode"
|
|
6961
|
+
];
|
|
6962
|
+
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;
|
|
6963
|
+
var STRONG_DEFENSIVE_CONTEXT_RE = /\b(?:security\s+(?:guidance|discussion|analysis)|threat\s+model|defensive)\b/i;
|
|
6964
|
+
var REPORTING_CONTEXT_RE = /\b(?:example|illustrat\w*|sample|quote|quoted|detector|scanner|classif\w*)\b/i;
|
|
6965
|
+
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;
|
|
6966
|
+
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;
|
|
6967
|
+
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;
|
|
6968
|
+
var PROMPT_INJECTION_RES = [
|
|
6969
|
+
/\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,
|
|
6970
|
+
/\b(?:new|following|these)\s+(?:(?:system|developer|assistant|hidden)\s+)?instructions?\b/i,
|
|
6971
|
+
/(?:^|\n)\s*(?:system|developer|instruction|prompt)\s*:/im,
|
|
6972
|
+
/<\s*(?:system|developer|assistant|instruction|prompt)\b[^>]*>/i,
|
|
6973
|
+
/\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
|
|
6974
|
+
];
|
|
6975
|
+
var TOOL_DIRECTIVE_RES = [
|
|
6976
|
+
/<\s*(?:tool[_-]?call|function[_-]?call|invoke|tool)\b/i,
|
|
6977
|
+
/\b(?:assistant|system)\s+to\s*=\s*[a-z0-9_.-]+/i,
|
|
6978
|
+
/\b(?:call|invoke|use|run|execute)\s+(?:the\s+)?[a-z0-9_.-]+\s+tool\b/i
|
|
6979
|
+
];
|
|
6980
|
+
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;
|
|
6981
|
+
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;
|
|
6982
|
+
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;
|
|
6983
|
+
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;
|
|
6984
|
+
function matchHasDefensiveContext(content, match) {
|
|
6985
|
+
if (!match || !match[0])
|
|
6986
|
+
return false;
|
|
6987
|
+
const start = match.index ?? 0;
|
|
6988
|
+
const before = content.slice(Math.max(0, start - 120), start);
|
|
6989
|
+
const after = content.slice(start + match[0].length, start + match[0].length + 160);
|
|
6990
|
+
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);
|
|
6991
|
+
}
|
|
6992
|
+
function hasActionableMatch(content, patterns) {
|
|
6993
|
+
return patterns.some((pattern) => {
|
|
6994
|
+
const flags = pattern.flags.includes("g") ? pattern.flags : `${pattern.flags}g`;
|
|
6995
|
+
const searchable = new RegExp(pattern.source, flags);
|
|
6996
|
+
let match;
|
|
6997
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
6998
|
+
if (!matchHasDefensiveContext(content, match))
|
|
6999
|
+
return true;
|
|
7000
|
+
if (match[0].length === 0)
|
|
7001
|
+
searchable.lastIndex += 1;
|
|
7002
|
+
}
|
|
7003
|
+
return false;
|
|
7004
|
+
});
|
|
7005
|
+
}
|
|
7006
|
+
function hasDangerousShell(content) {
|
|
7007
|
+
const searchable = new RegExp(DANGEROUS_SHELL_RE.source, `${DANGEROUS_SHELL_RE.flags}g`);
|
|
7008
|
+
let match;
|
|
7009
|
+
while ((match = searchable.exec(content)) !== null) {
|
|
7010
|
+
if (matchHasDefensiveContext(content, match))
|
|
7011
|
+
continue;
|
|
7012
|
+
const end = (match.index ?? 0) + match[0].length;
|
|
7013
|
+
const after = content.slice(end, end + 160);
|
|
7014
|
+
if (!STRONG_DEFENSIVE_CONTEXT_RE.test(after) && !REPORTING_AFTER_RE.test(after))
|
|
7015
|
+
return true;
|
|
7016
|
+
if (match[0].length === 0)
|
|
7017
|
+
searchable.lastIndex += 1;
|
|
7018
|
+
}
|
|
7019
|
+
return false;
|
|
7020
|
+
}
|
|
7021
|
+
function scanMemoryContent(content) {
|
|
7022
|
+
const raw = typeof content === "string" ? content : String(content ?? "");
|
|
7023
|
+
const normalized = raw.normalize("NFKC");
|
|
7024
|
+
const reasons = new Set;
|
|
7025
|
+
if (INVISIBLE_UNICODE_RE.test(raw))
|
|
7026
|
+
reasons.add("invisible_unicode");
|
|
7027
|
+
if (hasActionableMatch(normalized, PROMPT_INJECTION_RES))
|
|
7028
|
+
reasons.add("prompt_injection");
|
|
7029
|
+
if (hasActionableMatch(normalized, TOOL_DIRECTIVE_RES))
|
|
7030
|
+
reasons.add("tool_directive");
|
|
7031
|
+
if (hasActionableMatch(normalized, [EXFILTRATION_RE, EXFILTRATION_REVERSE]))
|
|
7032
|
+
reasons.add("exfiltration");
|
|
7033
|
+
if (hasActionableMatch(normalized, [CREDENTIAL_HARVESTING_RE]))
|
|
7034
|
+
reasons.add("credential_harvesting");
|
|
7035
|
+
if (hasDangerousShell(normalized))
|
|
7036
|
+
reasons.add("malicious_shell");
|
|
7037
|
+
const orderedReasons = MEMORY_CONTENT_SAFETY_REASONS.filter((reason) => reasons.has(reason));
|
|
7038
|
+
const status = orderedReasons.length === 0 ? "clean" : orderedReasons.every((reason) => reason === "invisible_unicode") ? "tainted" : "blocked";
|
|
7039
|
+
return {
|
|
7040
|
+
status,
|
|
7041
|
+
contextEligible: status === "clean",
|
|
7042
|
+
reasons: orderedReasons,
|
|
7043
|
+
policyVersion: MEMORY_CONTENT_SAFETY_POLICY_VERSION
|
|
7044
|
+
};
|
|
7045
|
+
}
|
|
6953
7046
|
var DAEMON_DERIVED_MEMORY_SOURCE_TYPES = ["extract", "aggregate-recall", "session_end", "checkpoint", "dreaming"];
|
|
6954
7047
|
var MEMORIES_FTS_TOKENIZER = "unicode61";
|
|
6955
7048
|
function normalizeSql(sql) {
|
|
@@ -10928,6 +11021,95 @@ function up124(db) {
|
|
|
10928
11021
|
ON imported_source_lifecycle(agent_id, status, updated_at DESC);
|
|
10929
11022
|
`);
|
|
10930
11023
|
}
|
|
11024
|
+
function tableExists2(db, table) {
|
|
11025
|
+
return db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
11026
|
+
}
|
|
11027
|
+
function hasColumn24(db, table, column) {
|
|
11028
|
+
return db.prepare(`PRAGMA table_info("${table}")`).all().some((row) => row.name === column);
|
|
11029
|
+
}
|
|
11030
|
+
function backfill(db, rows, sourceKind, scannedAt) {
|
|
11031
|
+
const statement = db.prepare(`INSERT INTO memory_content_safety
|
|
11032
|
+
(agent_id, source_kind, source_id, status, context_eligible, reasons_json, policy_version, scanned_at)
|
|
11033
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
11034
|
+
ON CONFLICT(agent_id, source_kind, source_id) DO UPDATE SET
|
|
11035
|
+
status = excluded.status,
|
|
11036
|
+
context_eligible = excluded.context_eligible,
|
|
11037
|
+
reasons_json = excluded.reasons_json,
|
|
11038
|
+
policy_version = excluded.policy_version,
|
|
11039
|
+
scanned_at = excluded.scanned_at`);
|
|
11040
|
+
for (const row of rows) {
|
|
11041
|
+
const sourceId = row.source_id?.trim();
|
|
11042
|
+
if (!sourceId)
|
|
11043
|
+
continue;
|
|
11044
|
+
const assessment = scanMemoryContent(row.content ?? "");
|
|
11045
|
+
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);
|
|
11046
|
+
}
|
|
11047
|
+
}
|
|
11048
|
+
function backfillTable(db, params) {
|
|
11049
|
+
if (!tableExists2(db, params.table) || !hasColumn24(db, params.table, params.sourceIdColumn) || !hasColumn24(db, params.table, params.contentColumn))
|
|
11050
|
+
return;
|
|
11051
|
+
const agentColumn = hasColumn24(db, params.table, "agent_id") ? "COALESCE(NULLIF(TRIM(agent_id), ''), 'default')" : "'default'";
|
|
11052
|
+
const rows = db.prepare(`SELECT ${agentColumn} AS agent_id, ${params.sourceIdColumn} AS source_id, ${params.contentColumn} AS content
|
|
11053
|
+
FROM ${params.table}${params.where ? ` WHERE ${params.where}` : ""}`).all();
|
|
11054
|
+
backfill(db, rows, params.sourceKind, params.scannedAt);
|
|
11055
|
+
}
|
|
11056
|
+
function up125(db) {
|
|
11057
|
+
db.exec(`
|
|
11058
|
+
CREATE TABLE IF NOT EXISTS memory_content_safety (
|
|
11059
|
+
agent_id TEXT NOT NULL,
|
|
11060
|
+
source_kind TEXT NOT NULL CHECK (source_kind IN ('memory', 'artifact', 'transcript', 'summary', 'source_chunk')),
|
|
11061
|
+
source_id TEXT NOT NULL,
|
|
11062
|
+
status TEXT NOT NULL CHECK (status IN ('clean', 'tainted', 'blocked')),
|
|
11063
|
+
context_eligible INTEGER NOT NULL CHECK (context_eligible IN (0, 1)),
|
|
11064
|
+
reasons_json TEXT NOT NULL DEFAULT '[]',
|
|
11065
|
+
policy_version TEXT NOT NULL,
|
|
11066
|
+
scanned_at TEXT NOT NULL,
|
|
11067
|
+
PRIMARY KEY (agent_id, source_kind, source_id)
|
|
11068
|
+
);
|
|
11069
|
+
|
|
11070
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_status
|
|
11071
|
+
ON memory_content_safety(agent_id, status, source_kind);
|
|
11072
|
+
CREATE INDEX IF NOT EXISTS idx_memory_content_safety_eligibility
|
|
11073
|
+
ON memory_content_safety(agent_id, source_kind, context_eligible);
|
|
11074
|
+
`);
|
|
11075
|
+
const scannedAt = new Date().toISOString();
|
|
11076
|
+
backfillTable(db, {
|
|
11077
|
+
table: "memories",
|
|
11078
|
+
sourceKind: "memory",
|
|
11079
|
+
sourceIdColumn: "id",
|
|
11080
|
+
contentColumn: "content",
|
|
11081
|
+
scannedAt
|
|
11082
|
+
});
|
|
11083
|
+
backfillTable(db, {
|
|
11084
|
+
table: "memory_artifacts",
|
|
11085
|
+
sourceKind: "artifact",
|
|
11086
|
+
sourceIdColumn: "source_path",
|
|
11087
|
+
contentColumn: "content",
|
|
11088
|
+
scannedAt
|
|
11089
|
+
});
|
|
11090
|
+
backfillTable(db, {
|
|
11091
|
+
table: "session_transcripts",
|
|
11092
|
+
sourceKind: "transcript",
|
|
11093
|
+
sourceIdColumn: "session_key",
|
|
11094
|
+
contentColumn: "content",
|
|
11095
|
+
scannedAt
|
|
11096
|
+
});
|
|
11097
|
+
backfillTable(db, {
|
|
11098
|
+
table: "session_summaries",
|
|
11099
|
+
sourceKind: "summary",
|
|
11100
|
+
sourceIdColumn: "id",
|
|
11101
|
+
contentColumn: "content",
|
|
11102
|
+
scannedAt
|
|
11103
|
+
});
|
|
11104
|
+
backfillTable(db, {
|
|
11105
|
+
table: "embeddings",
|
|
11106
|
+
sourceKind: "source_chunk",
|
|
11107
|
+
sourceIdColumn: "id",
|
|
11108
|
+
contentColumn: "chunk_text",
|
|
11109
|
+
where: "source_type IN ('source_chunk', 'source_obsidian_chunk')",
|
|
11110
|
+
scannedAt
|
|
11111
|
+
});
|
|
11112
|
+
}
|
|
10931
11113
|
var MIGRATIONS = [
|
|
10932
11114
|
{
|
|
10933
11115
|
version: 1,
|
|
@@ -11936,6 +12118,12 @@ var MIGRATIONS = [
|
|
|
11936
12118
|
artifacts: {
|
|
11937
12119
|
tables: ["imported_source_lifecycle"]
|
|
11938
12120
|
}
|
|
12121
|
+
},
|
|
12122
|
+
{
|
|
12123
|
+
version: 125,
|
|
12124
|
+
name: "memory-content-safety",
|
|
12125
|
+
up: up125,
|
|
12126
|
+
artifacts: { tables: ["memory_content_safety"] }
|
|
11939
12127
|
}
|
|
11940
12128
|
];
|
|
11941
12129
|
var LATEST_SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signetai/connector-base",
|
|
3
|
-
"version": "0.193.
|
|
3
|
+
"version": "0.193.2",
|
|
4
4
|
"description": "Base class for Signet harness connectors",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"typecheck": "tsc --noEmit"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@signetai/core": "0.193.
|
|
29
|
+
"@signetai/core": "0.193.2",
|
|
30
30
|
"json5": "^2.2.3",
|
|
31
31
|
"jsonc-parser": "3.3.1"
|
|
32
32
|
},
|