@signetai/connector-openclaw 0.185.4 → 0.185.5
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 +485 -25
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { dirname as dirname5, isAbsolute, join as join3, relative, sep } from "n
|
|
|
10
10
|
import { createRequire } from "node:module";
|
|
11
11
|
import { dirname, join } from "node:path";
|
|
12
12
|
import { fileURLToPath } from "node:url";
|
|
13
|
+
import { createHash } from "node:crypto";
|
|
13
14
|
import { createRequire as createRequire2 } from "node:module";
|
|
14
15
|
import { homedir as homedir4 } from "node:os";
|
|
15
16
|
import { dirname as dirname3, join as join6, resolve as resolve2 } from "node:path";
|
|
@@ -10541,6 +10542,224 @@ function up116(db) {
|
|
|
10541
10542
|
ON cross_agent_messages(delivery_path, delivery_state, delivery_lease_expires_at, delivery_updated_at);
|
|
10542
10543
|
`);
|
|
10543
10544
|
}
|
|
10545
|
+
function hasTable4(db, table) {
|
|
10546
|
+
return db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
10547
|
+
}
|
|
10548
|
+
function addColumnIfMissing25(db, table, column, definition) {
|
|
10549
|
+
const columns = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
10550
|
+
if (columns.some((row) => row.name === column))
|
|
10551
|
+
return;
|
|
10552
|
+
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
10553
|
+
}
|
|
10554
|
+
function tableColumns(db, table) {
|
|
10555
|
+
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
10556
|
+
return new Set(rows.map((row) => typeof row.name === "string" ? row.name : ""));
|
|
10557
|
+
}
|
|
10558
|
+
function hashTranscript(content) {
|
|
10559
|
+
return createHash("sha256").update(content, "utf8").digest("hex");
|
|
10560
|
+
}
|
|
10561
|
+
function backfillTranscriptHashes(db) {
|
|
10562
|
+
const columns = tableColumns(db, "session_transcripts");
|
|
10563
|
+
if (!columns.has("content_hash") || !columns.has("content"))
|
|
10564
|
+
return;
|
|
10565
|
+
const rows = db.prepare("SELECT session_key, agent_id, content FROM session_transcripts WHERE content_hash IS NULL").all();
|
|
10566
|
+
const update = db.prepare("UPDATE session_transcripts SET content_hash = ? WHERE agent_id = ? AND session_key = ? AND content_hash IS NULL");
|
|
10567
|
+
for (const row of rows) {
|
|
10568
|
+
if (typeof row.content !== "string" || typeof row.session_key !== "string")
|
|
10569
|
+
continue;
|
|
10570
|
+
update.run(hashTranscript(row.content), typeof row.agent_id === "string" ? row.agent_id : "default", row.session_key);
|
|
10571
|
+
}
|
|
10572
|
+
}
|
|
10573
|
+
var COMPLETION_BOUNDARY_REASONS = new Set(["session_closed", "session_clear", "stale_session", "ttl_expired"]);
|
|
10574
|
+
function summaryJobTimestamp(job) {
|
|
10575
|
+
return job.completed_at ?? job.ended_at ?? job.captured_at ?? job.created_at ?? new Date(0).toISOString();
|
|
10576
|
+
}
|
|
10577
|
+
function laterTimestamp(current, candidate) {
|
|
10578
|
+
if (current === null)
|
|
10579
|
+
return candidate;
|
|
10580
|
+
if (candidate === null)
|
|
10581
|
+
return current;
|
|
10582
|
+
const currentMillis = Date.parse(current);
|
|
10583
|
+
const candidateMillis = Date.parse(candidate);
|
|
10584
|
+
if (Number.isFinite(currentMillis) && Number.isFinite(candidateMillis)) {
|
|
10585
|
+
return candidateMillis > currentMillis ? candidate : current;
|
|
10586
|
+
}
|
|
10587
|
+
return candidate > current ? candidate : current;
|
|
10588
|
+
}
|
|
10589
|
+
function isCompletionBoundary(job, columns) {
|
|
10590
|
+
return columns.has("trigger") && job.trigger === "session_end" || columns.has("boundary_reason") && COMPLETION_BOUNDARY_REASONS.has(job.boundary_reason ?? "");
|
|
10591
|
+
}
|
|
10592
|
+
function mergeTranscriptContent(current, next) {
|
|
10593
|
+
if (current.length === 0)
|
|
10594
|
+
return next;
|
|
10595
|
+
if (next.length === 0 || current === next || current.includes(next))
|
|
10596
|
+
return current;
|
|
10597
|
+
if (next.includes(current))
|
|
10598
|
+
return next;
|
|
10599
|
+
return `${current}
|
|
10600
|
+
${next}`;
|
|
10601
|
+
}
|
|
10602
|
+
function backfillTranscriptsFromSummaryJobs(db) {
|
|
10603
|
+
if (!hasTable4(db, "summary_jobs"))
|
|
10604
|
+
return;
|
|
10605
|
+
const summaryColumns = tableColumns(db, "summary_jobs");
|
|
10606
|
+
if (!summaryColumns.has("transcript"))
|
|
10607
|
+
return;
|
|
10608
|
+
const select = (name) => summaryColumns.has(name) ? `"${name}" AS "${name}"` : `NULL AS "${name}"`;
|
|
10609
|
+
const jobs = db.prepare(`SELECT ${[
|
|
10610
|
+
"id",
|
|
10611
|
+
"session_key",
|
|
10612
|
+
"transcript",
|
|
10613
|
+
"harness",
|
|
10614
|
+
"project",
|
|
10615
|
+
"agent_id",
|
|
10616
|
+
"trigger",
|
|
10617
|
+
"boundary_reason",
|
|
10618
|
+
"captured_at",
|
|
10619
|
+
"ended_at",
|
|
10620
|
+
"completed_at",
|
|
10621
|
+
"created_at"
|
|
10622
|
+
].map(select).join(", ")} FROM summary_jobs`).all();
|
|
10623
|
+
const candidates = new Map;
|
|
10624
|
+
for (const job of jobs) {
|
|
10625
|
+
if (typeof job.transcript !== "string" || job.transcript.trim().length === 0)
|
|
10626
|
+
continue;
|
|
10627
|
+
const agentId = typeof job.agent_id === "string" && job.agent_id.length > 0 ? job.agent_id : "default";
|
|
10628
|
+
const sessionKey = typeof job.session_key === "string" && job.session_key.trim().length > 0 ? job.session_key : `legacy-summary-job:${job.id ?? hashTranscript(`${summaryJobTimestamp(job)}\x00${job.transcript}`)}`;
|
|
10629
|
+
const key = `${agentId}\x00${sessionKey}`;
|
|
10630
|
+
const current = candidates.get(key);
|
|
10631
|
+
const timestamp = summaryJobTimestamp(job);
|
|
10632
|
+
const boundary = isCompletionBoundary(job, summaryColumns);
|
|
10633
|
+
const createdAt = job.captured_at ?? job.created_at ?? job.ended_at ?? timestamp;
|
|
10634
|
+
if (!current) {
|
|
10635
|
+
candidates.set(key, {
|
|
10636
|
+
sessionKey,
|
|
10637
|
+
job: { ...job, agent_id: agentId },
|
|
10638
|
+
content: job.transcript,
|
|
10639
|
+
createdAt,
|
|
10640
|
+
completedAt: boundary ? timestamp : null
|
|
10641
|
+
});
|
|
10642
|
+
continue;
|
|
10643
|
+
}
|
|
10644
|
+
const currentTimestamp = summaryJobTimestamp(current.job);
|
|
10645
|
+
const preferred = timestamp > currentTimestamp || timestamp === currentTimestamp && job.transcript.length > current.content.length ? { ...job, agent_id: agentId } : current.job;
|
|
10646
|
+
candidates.set(key, {
|
|
10647
|
+
sessionKey,
|
|
10648
|
+
job: preferred,
|
|
10649
|
+
content: mergeTranscriptContent(current.content, job.transcript),
|
|
10650
|
+
createdAt: current.createdAt < createdAt ? current.createdAt : createdAt,
|
|
10651
|
+
completedAt: laterTimestamp(current.completedAt, boundary ? timestamp : null)
|
|
10652
|
+
});
|
|
10653
|
+
}
|
|
10654
|
+
const transcriptColumns = tableColumns(db, "session_transcripts");
|
|
10655
|
+
const hasUpdated = transcriptColumns.has("updated_at");
|
|
10656
|
+
const hasCompleted = transcriptColumns.has("completed_at");
|
|
10657
|
+
const hasHash = transcriptColumns.has("content_hash");
|
|
10658
|
+
const insertColumns = ["session_key", "content", "harness", "project", "agent_id", "created_at"];
|
|
10659
|
+
if (hasUpdated)
|
|
10660
|
+
insertColumns.push("updated_at");
|
|
10661
|
+
if (hasCompleted)
|
|
10662
|
+
insertColumns.push("completed_at");
|
|
10663
|
+
if (hasHash)
|
|
10664
|
+
insertColumns.push("content_hash");
|
|
10665
|
+
const insert = db.prepare(`INSERT OR IGNORE INTO session_transcripts (${insertColumns.join(", ")}) VALUES (${insertColumns.map(() => "?").join(", ")})`);
|
|
10666
|
+
const existing = db.prepare("SELECT content, completed_at FROM session_transcripts WHERE agent_id = ? AND session_key = ?");
|
|
10667
|
+
for (const candidate of candidates.values()) {
|
|
10668
|
+
const job = candidate.job;
|
|
10669
|
+
const agentId = job.agent_id ?? "default";
|
|
10670
|
+
const existingRow = existing.get(agentId, candidate.sessionKey);
|
|
10671
|
+
if (existingRow != null) {
|
|
10672
|
+
const previousContent = typeof existingRow.content === "string" ? existingRow.content : "";
|
|
10673
|
+
const mergedContent = mergeTranscriptContent(previousContent, candidate.content);
|
|
10674
|
+
const completedAt = typeof existingRow.completed_at === "string" && existingRow.completed_at.length > 0 ? existingRow.completed_at : candidate.completedAt;
|
|
10675
|
+
const assignments = ["content = ?"];
|
|
10676
|
+
const values2 = [mergedContent];
|
|
10677
|
+
if (hasUpdated && mergedContent !== previousContent) {
|
|
10678
|
+
assignments.push("updated_at = ?");
|
|
10679
|
+
values2.push(candidate.createdAt);
|
|
10680
|
+
}
|
|
10681
|
+
if (hasCompleted && completedAt && !existingRow.completed_at) {
|
|
10682
|
+
assignments.push("completed_at = ?");
|
|
10683
|
+
values2.push(completedAt);
|
|
10684
|
+
}
|
|
10685
|
+
if (hasHash) {
|
|
10686
|
+
assignments.push("content_hash = ?");
|
|
10687
|
+
values2.push(hashTranscript(mergedContent));
|
|
10688
|
+
}
|
|
10689
|
+
values2.push(agentId, candidate.sessionKey);
|
|
10690
|
+
db.prepare(`UPDATE session_transcripts SET ${assignments.join(", ")} WHERE agent_id = ? AND session_key = ?`).run(...values2);
|
|
10691
|
+
continue;
|
|
10692
|
+
}
|
|
10693
|
+
const values = [
|
|
10694
|
+
candidate.sessionKey,
|
|
10695
|
+
candidate.content,
|
|
10696
|
+
job.harness ?? null,
|
|
10697
|
+
job.project ?? null,
|
|
10698
|
+
agentId,
|
|
10699
|
+
candidate.createdAt
|
|
10700
|
+
];
|
|
10701
|
+
if (hasUpdated)
|
|
10702
|
+
values.push(candidate.createdAt);
|
|
10703
|
+
if (hasCompleted)
|
|
10704
|
+
values.push(candidate.completedAt);
|
|
10705
|
+
if (hasHash)
|
|
10706
|
+
values.push(hashTranscript(candidate.content));
|
|
10707
|
+
insert.run(...values);
|
|
10708
|
+
}
|
|
10709
|
+
}
|
|
10710
|
+
function up117(db) {
|
|
10711
|
+
if (!hasTable4(db, "session_transcripts"))
|
|
10712
|
+
return;
|
|
10713
|
+
addColumnIfMissing25(db, "session_transcripts", "completed_at", "TEXT");
|
|
10714
|
+
addColumnIfMissing25(db, "session_transcripts", "content_hash", "TEXT");
|
|
10715
|
+
backfillTranscriptHashes(db);
|
|
10716
|
+
if (hasTable4(db, "transcript_capture_jobs")) {
|
|
10717
|
+
const captureColumns = db.prepare("PRAGMA table_info(transcript_capture_jobs)").all();
|
|
10718
|
+
if (captureColumns.some((row) => row.name === "summary_status")) {
|
|
10719
|
+
db.exec("UPDATE transcript_capture_jobs SET summary_status = 'not_requested' WHERE summary_status IN ('pending', 'failed', 'skipped')");
|
|
10720
|
+
}
|
|
10721
|
+
}
|
|
10722
|
+
if (hasTable4(db, "summary_jobs")) {
|
|
10723
|
+
backfillTranscriptsFromSummaryJobs(db);
|
|
10724
|
+
backfillTranscriptHashes(db);
|
|
10725
|
+
const summaryColumns = tableColumns(db, "summary_jobs");
|
|
10726
|
+
const timestampParts = ["completed_at", "ended_at", "captured_at", "created_at"].filter((column) => summaryColumns.has(column)).map((column) => `sj.${column}`);
|
|
10727
|
+
const timestampValue = timestampParts.length === 1 ? timestampParts[0] : `COALESCE(${timestampParts.join(", ")})`;
|
|
10728
|
+
const completionTimestamp = timestampValue ? `MAX(${timestampValue})` : "NULL";
|
|
10729
|
+
const boundaryParts = [
|
|
10730
|
+
summaryColumns.has("trigger") ? "sj.trigger = 'session_end'" : null,
|
|
10731
|
+
summaryColumns.has("boundary_reason") ? "sj.boundary_reason IN ('session_closed', 'session_clear', 'stale_session', 'ttl_expired')" : null
|
|
10732
|
+
].filter((part) => part !== null);
|
|
10733
|
+
const boundaryPredicate = boundaryParts.length > 0 ? `(${boundaryParts.join(" OR ")})` : "1=1";
|
|
10734
|
+
const agentPredicate = summaryColumns.has("agent_id") ? "sj.agent_id = session_transcripts.agent_id" : "session_transcripts.agent_id = 'default'";
|
|
10735
|
+
if (completionTimestamp !== "NULL") {
|
|
10736
|
+
db.exec(`
|
|
10737
|
+
UPDATE session_transcripts
|
|
10738
|
+
SET completed_at = COALESCE(
|
|
10739
|
+
completed_at,
|
|
10740
|
+
(
|
|
10741
|
+
SELECT ${completionTimestamp}
|
|
10742
|
+
FROM summary_jobs AS sj
|
|
10743
|
+
WHERE ${agentPredicate}
|
|
10744
|
+
AND sj.session_key = session_transcripts.session_key
|
|
10745
|
+
AND ${boundaryPredicate}
|
|
10746
|
+
)
|
|
10747
|
+
)
|
|
10748
|
+
WHERE completed_at IS NULL;
|
|
10749
|
+
`);
|
|
10750
|
+
}
|
|
10751
|
+
db.exec("DELETE FROM summary_jobs");
|
|
10752
|
+
}
|
|
10753
|
+
const completionIndexColumns = ["agent_id", "completed_at"];
|
|
10754
|
+
if (tableColumns(db, "session_transcripts").has("updated_at"))
|
|
10755
|
+
completionIndexColumns.push("updated_at");
|
|
10756
|
+
db.exec(`
|
|
10757
|
+
CREATE INDEX IF NOT EXISTS idx_st_agent_completed
|
|
10758
|
+
ON session_transcripts(${completionIndexColumns.join(", ")});
|
|
10759
|
+
CREATE INDEX IF NOT EXISTS idx_st_agent_hash
|
|
10760
|
+
ON session_transcripts(agent_id, content_hash);
|
|
10761
|
+
`);
|
|
10762
|
+
}
|
|
10544
10763
|
var MIGRATIONS = [
|
|
10545
10764
|
{
|
|
10546
10765
|
version: 1,
|
|
@@ -11480,6 +11699,17 @@ var MIGRATIONS = [
|
|
|
11480
11699
|
{ table: "cross_agent_messages", column: "acp_target_agent_name" }
|
|
11481
11700
|
]
|
|
11482
11701
|
}
|
|
11702
|
+
},
|
|
11703
|
+
{
|
|
11704
|
+
version: 117,
|
|
11705
|
+
name: "retire-summary-worker",
|
|
11706
|
+
up: up117,
|
|
11707
|
+
artifacts: {
|
|
11708
|
+
columns: [
|
|
11709
|
+
{ table: "session_transcripts", column: "completed_at" },
|
|
11710
|
+
{ table: "session_transcripts", column: "content_hash" }
|
|
11711
|
+
]
|
|
11712
|
+
}
|
|
11483
11713
|
}
|
|
11484
11714
|
];
|
|
11485
11715
|
var LATEST_SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0;
|
|
@@ -13791,6 +14021,7 @@ function parseLenientJsonObject(raw, options) {
|
|
|
13791
14021
|
import { createRequire as createRequire3 } from "node:module";
|
|
13792
14022
|
import { dirname as dirname2, join as join2 } from "node:path";
|
|
13793
14023
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
14024
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
13794
14025
|
import { homedir as homedir2 } from "os";
|
|
13795
14026
|
import { join as join22 } from "path";
|
|
13796
14027
|
import { createRequire as createRequire22 } from "node:module";
|
|
@@ -20746,7 +20977,7 @@ function memoriesFtsNeedsTokenizerRepair2(sql) {
|
|
|
20746
20977
|
return true;
|
|
20747
20978
|
return !normalized.includes(`tokenize='${MEMORIES_FTS_TOKENIZER2}'`);
|
|
20748
20979
|
}
|
|
20749
|
-
function
|
|
20980
|
+
function up118(db) {
|
|
20750
20981
|
db.exec(`
|
|
20751
20982
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
20752
20983
|
version INTEGER PRIMARY KEY,
|
|
@@ -20839,27 +21070,27 @@ function hasColumn22(db, table, column) {
|
|
|
20839
21070
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
20840
21071
|
return rows.some((r) => r.name === column);
|
|
20841
21072
|
}
|
|
20842
|
-
function
|
|
21073
|
+
function addColumnIfMissing26(db, table, column, definition) {
|
|
20843
21074
|
if (!hasColumn22(db, table, column)) {
|
|
20844
21075
|
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
20845
21076
|
}
|
|
20846
21077
|
}
|
|
20847
21078
|
function up210(db) {
|
|
20848
|
-
|
|
20849
|
-
|
|
20850
|
-
|
|
20851
|
-
|
|
20852
|
-
|
|
20853
|
-
|
|
20854
|
-
|
|
20855
|
-
|
|
20856
|
-
|
|
20857
|
-
|
|
20858
|
-
|
|
20859
|
-
|
|
20860
|
-
|
|
20861
|
-
|
|
20862
|
-
|
|
21079
|
+
addColumnIfMissing26(db, "memories", "content_hash", "TEXT");
|
|
21080
|
+
addColumnIfMissing26(db, "memories", "normalized_content", "TEXT");
|
|
21081
|
+
addColumnIfMissing26(db, "memories", "is_deleted", "INTEGER DEFAULT 0");
|
|
21082
|
+
addColumnIfMissing26(db, "memories", "deleted_at", "TEXT");
|
|
21083
|
+
addColumnIfMissing26(db, "memories", "extraction_status", "TEXT DEFAULT 'none'");
|
|
21084
|
+
addColumnIfMissing26(db, "memories", "embedding_model", "TEXT");
|
|
21085
|
+
addColumnIfMissing26(db, "memories", "extraction_model", "TEXT");
|
|
21086
|
+
addColumnIfMissing26(db, "memories", "update_count", "INTEGER DEFAULT 0");
|
|
21087
|
+
addColumnIfMissing26(db, "memories", "who", "TEXT");
|
|
21088
|
+
addColumnIfMissing26(db, "memories", "why", "TEXT");
|
|
21089
|
+
addColumnIfMissing26(db, "memories", "project", "TEXT");
|
|
21090
|
+
addColumnIfMissing26(db, "memories", "pinned", "INTEGER DEFAULT 0");
|
|
21091
|
+
addColumnIfMissing26(db, "memories", "importance", "REAL DEFAULT 0.5");
|
|
21092
|
+
addColumnIfMissing26(db, "memories", "last_accessed", "TEXT");
|
|
21093
|
+
addColumnIfMissing26(db, "memories", "access_count", "INTEGER DEFAULT 0");
|
|
20863
21094
|
db.exec(`
|
|
20864
21095
|
CREATE TABLE IF NOT EXISTS memory_history (
|
|
20865
21096
|
id TEXT PRIMARY KEY,
|
|
@@ -20955,7 +21186,7 @@ function up210(db) {
|
|
|
20955
21186
|
ON memory_entity_mentions(entity_id);
|
|
20956
21187
|
`);
|
|
20957
21188
|
}
|
|
20958
|
-
function
|
|
21189
|
+
function addColumnIfMissing27(db, table, column, definition) {
|
|
20959
21190
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
20960
21191
|
if (rows.some((r) => r.name === column))
|
|
20961
21192
|
return false;
|
|
@@ -20963,8 +21194,8 @@ function addColumnIfMissing26(db, table, column, definition) {
|
|
|
20963
21194
|
return true;
|
|
20964
21195
|
}
|
|
20965
21196
|
function up310(db) {
|
|
20966
|
-
|
|
20967
|
-
|
|
21197
|
+
addColumnIfMissing27(db, "memories", "why", "TEXT");
|
|
21198
|
+
addColumnIfMissing27(db, "memories", "project", "TEXT");
|
|
20968
21199
|
db.exec(`DROP INDEX IF EXISTS idx_memories_content_hash`);
|
|
20969
21200
|
db.exec(`
|
|
20970
21201
|
UPDATE memories
|
|
@@ -21169,7 +21400,7 @@ function up1010(db) {
|
|
|
21169
21400
|
)
|
|
21170
21401
|
`);
|
|
21171
21402
|
}
|
|
21172
|
-
function
|
|
21403
|
+
function up119(db) {
|
|
21173
21404
|
db.exec(`
|
|
21174
21405
|
CREATE TABLE IF NOT EXISTS session_scores (
|
|
21175
21406
|
id TEXT PRIMARY KEY,
|
|
@@ -22390,7 +22621,7 @@ function up492(db) {
|
|
|
22390
22621
|
);
|
|
22391
22622
|
`);
|
|
22392
22623
|
}
|
|
22393
|
-
function
|
|
22624
|
+
function hasTable5(db, name) {
|
|
22394
22625
|
return db.prepare(`SELECT name
|
|
22395
22626
|
FROM sqlite_master
|
|
22396
22627
|
WHERE type = 'table' AND name = ?
|
|
@@ -22420,7 +22651,7 @@ function up502(db) {
|
|
|
22420
22651
|
CREATE INDEX IF NOT EXISTS idx_entity_dependency_history_created
|
|
22421
22652
|
ON entity_dependency_history(created_at DESC);
|
|
22422
22653
|
`);
|
|
22423
|
-
if (!
|
|
22654
|
+
if (!hasTable5(db, "entity_dependencies"))
|
|
22424
22655
|
return;
|
|
22425
22656
|
db.exec("DROP TRIGGER IF EXISTS trg_entity_dependencies_related_to_reason_insert");
|
|
22426
22657
|
db.exec("DROP TRIGGER IF EXISTS trg_entity_dependencies_related_to_reason_update");
|
|
@@ -24322,11 +24553,229 @@ function up1162(db) {
|
|
|
24322
24553
|
ON cross_agent_messages(delivery_path, delivery_state, delivery_lease_expires_at, delivery_updated_at);
|
|
24323
24554
|
`);
|
|
24324
24555
|
}
|
|
24556
|
+
function hasTable42(db, table) {
|
|
24557
|
+
return db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
24558
|
+
}
|
|
24559
|
+
function addColumnIfMissing252(db, table, column, definition) {
|
|
24560
|
+
const columns = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
24561
|
+
if (columns.some((row) => row.name === column))
|
|
24562
|
+
return;
|
|
24563
|
+
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
24564
|
+
}
|
|
24565
|
+
function tableColumns2(db, table) {
|
|
24566
|
+
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
24567
|
+
return new Set(rows.map((row) => typeof row.name === "string" ? row.name : ""));
|
|
24568
|
+
}
|
|
24569
|
+
function hashTranscript2(content) {
|
|
24570
|
+
return createHash2("sha256").update(content, "utf8").digest("hex");
|
|
24571
|
+
}
|
|
24572
|
+
function backfillTranscriptHashes2(db) {
|
|
24573
|
+
const columns = tableColumns2(db, "session_transcripts");
|
|
24574
|
+
if (!columns.has("content_hash") || !columns.has("content"))
|
|
24575
|
+
return;
|
|
24576
|
+
const rows = db.prepare("SELECT session_key, agent_id, content FROM session_transcripts WHERE content_hash IS NULL").all();
|
|
24577
|
+
const update = db.prepare("UPDATE session_transcripts SET content_hash = ? WHERE agent_id = ? AND session_key = ? AND content_hash IS NULL");
|
|
24578
|
+
for (const row of rows) {
|
|
24579
|
+
if (typeof row.content !== "string" || typeof row.session_key !== "string")
|
|
24580
|
+
continue;
|
|
24581
|
+
update.run(hashTranscript2(row.content), typeof row.agent_id === "string" ? row.agent_id : "default", row.session_key);
|
|
24582
|
+
}
|
|
24583
|
+
}
|
|
24584
|
+
var COMPLETION_BOUNDARY_REASONS2 = new Set(["session_closed", "session_clear", "stale_session", "ttl_expired"]);
|
|
24585
|
+
function summaryJobTimestamp2(job) {
|
|
24586
|
+
return job.completed_at ?? job.ended_at ?? job.captured_at ?? job.created_at ?? new Date(0).toISOString();
|
|
24587
|
+
}
|
|
24588
|
+
function laterTimestamp2(current, candidate) {
|
|
24589
|
+
if (current === null)
|
|
24590
|
+
return candidate;
|
|
24591
|
+
if (candidate === null)
|
|
24592
|
+
return current;
|
|
24593
|
+
const currentMillis = Date.parse(current);
|
|
24594
|
+
const candidateMillis = Date.parse(candidate);
|
|
24595
|
+
if (Number.isFinite(currentMillis) && Number.isFinite(candidateMillis)) {
|
|
24596
|
+
return candidateMillis > currentMillis ? candidate : current;
|
|
24597
|
+
}
|
|
24598
|
+
return candidate > current ? candidate : current;
|
|
24599
|
+
}
|
|
24600
|
+
function isCompletionBoundary2(job, columns) {
|
|
24601
|
+
return columns.has("trigger") && job.trigger === "session_end" || columns.has("boundary_reason") && COMPLETION_BOUNDARY_REASONS2.has(job.boundary_reason ?? "");
|
|
24602
|
+
}
|
|
24603
|
+
function mergeTranscriptContent2(current, next) {
|
|
24604
|
+
if (current.length === 0)
|
|
24605
|
+
return next;
|
|
24606
|
+
if (next.length === 0 || current === next || current.includes(next))
|
|
24607
|
+
return current;
|
|
24608
|
+
if (next.includes(current))
|
|
24609
|
+
return next;
|
|
24610
|
+
return `${current}
|
|
24611
|
+
${next}`;
|
|
24612
|
+
}
|
|
24613
|
+
function backfillTranscriptsFromSummaryJobs2(db) {
|
|
24614
|
+
if (!hasTable42(db, "summary_jobs"))
|
|
24615
|
+
return;
|
|
24616
|
+
const summaryColumns = tableColumns2(db, "summary_jobs");
|
|
24617
|
+
if (!summaryColumns.has("transcript"))
|
|
24618
|
+
return;
|
|
24619
|
+
const select = (name) => summaryColumns.has(name) ? `"${name}" AS "${name}"` : `NULL AS "${name}"`;
|
|
24620
|
+
const jobs = db.prepare(`SELECT ${[
|
|
24621
|
+
"id",
|
|
24622
|
+
"session_key",
|
|
24623
|
+
"transcript",
|
|
24624
|
+
"harness",
|
|
24625
|
+
"project",
|
|
24626
|
+
"agent_id",
|
|
24627
|
+
"trigger",
|
|
24628
|
+
"boundary_reason",
|
|
24629
|
+
"captured_at",
|
|
24630
|
+
"ended_at",
|
|
24631
|
+
"completed_at",
|
|
24632
|
+
"created_at"
|
|
24633
|
+
].map(select).join(", ")} FROM summary_jobs`).all();
|
|
24634
|
+
const candidates = new Map;
|
|
24635
|
+
for (const job of jobs) {
|
|
24636
|
+
if (typeof job.transcript !== "string" || job.transcript.trim().length === 0)
|
|
24637
|
+
continue;
|
|
24638
|
+
const agentId = typeof job.agent_id === "string" && job.agent_id.length > 0 ? job.agent_id : "default";
|
|
24639
|
+
const sessionKey = typeof job.session_key === "string" && job.session_key.trim().length > 0 ? job.session_key : `legacy-summary-job:${job.id ?? hashTranscript2(`${summaryJobTimestamp2(job)}\x00${job.transcript}`)}`;
|
|
24640
|
+
const key = `${agentId}\x00${sessionKey}`;
|
|
24641
|
+
const current = candidates.get(key);
|
|
24642
|
+
const timestamp = summaryJobTimestamp2(job);
|
|
24643
|
+
const boundary = isCompletionBoundary2(job, summaryColumns);
|
|
24644
|
+
const createdAt = job.captured_at ?? job.created_at ?? job.ended_at ?? timestamp;
|
|
24645
|
+
if (!current) {
|
|
24646
|
+
candidates.set(key, {
|
|
24647
|
+
sessionKey,
|
|
24648
|
+
job: { ...job, agent_id: agentId },
|
|
24649
|
+
content: job.transcript,
|
|
24650
|
+
createdAt,
|
|
24651
|
+
completedAt: boundary ? timestamp : null
|
|
24652
|
+
});
|
|
24653
|
+
continue;
|
|
24654
|
+
}
|
|
24655
|
+
const currentTimestamp = summaryJobTimestamp2(current.job);
|
|
24656
|
+
const preferred = timestamp > currentTimestamp || timestamp === currentTimestamp && job.transcript.length > current.content.length ? { ...job, agent_id: agentId } : current.job;
|
|
24657
|
+
candidates.set(key, {
|
|
24658
|
+
sessionKey,
|
|
24659
|
+
job: preferred,
|
|
24660
|
+
content: mergeTranscriptContent2(current.content, job.transcript),
|
|
24661
|
+
createdAt: current.createdAt < createdAt ? current.createdAt : createdAt,
|
|
24662
|
+
completedAt: laterTimestamp2(current.completedAt, boundary ? timestamp : null)
|
|
24663
|
+
});
|
|
24664
|
+
}
|
|
24665
|
+
const transcriptColumns = tableColumns2(db, "session_transcripts");
|
|
24666
|
+
const hasUpdated = transcriptColumns.has("updated_at");
|
|
24667
|
+
const hasCompleted = transcriptColumns.has("completed_at");
|
|
24668
|
+
const hasHash = transcriptColumns.has("content_hash");
|
|
24669
|
+
const insertColumns = ["session_key", "content", "harness", "project", "agent_id", "created_at"];
|
|
24670
|
+
if (hasUpdated)
|
|
24671
|
+
insertColumns.push("updated_at");
|
|
24672
|
+
if (hasCompleted)
|
|
24673
|
+
insertColumns.push("completed_at");
|
|
24674
|
+
if (hasHash)
|
|
24675
|
+
insertColumns.push("content_hash");
|
|
24676
|
+
const insert = db.prepare(`INSERT OR IGNORE INTO session_transcripts (${insertColumns.join(", ")}) VALUES (${insertColumns.map(() => "?").join(", ")})`);
|
|
24677
|
+
const existing = db.prepare("SELECT content, completed_at FROM session_transcripts WHERE agent_id = ? AND session_key = ?");
|
|
24678
|
+
for (const candidate of candidates.values()) {
|
|
24679
|
+
const job = candidate.job;
|
|
24680
|
+
const agentId = job.agent_id ?? "default";
|
|
24681
|
+
const existingRow = existing.get(agentId, candidate.sessionKey);
|
|
24682
|
+
if (existingRow != null) {
|
|
24683
|
+
const previousContent = typeof existingRow.content === "string" ? existingRow.content : "";
|
|
24684
|
+
const mergedContent = mergeTranscriptContent2(previousContent, candidate.content);
|
|
24685
|
+
const completedAt = typeof existingRow.completed_at === "string" && existingRow.completed_at.length > 0 ? existingRow.completed_at : candidate.completedAt;
|
|
24686
|
+
const assignments = ["content = ?"];
|
|
24687
|
+
const values2 = [mergedContent];
|
|
24688
|
+
if (hasUpdated && mergedContent !== previousContent) {
|
|
24689
|
+
assignments.push("updated_at = ?");
|
|
24690
|
+
values2.push(candidate.createdAt);
|
|
24691
|
+
}
|
|
24692
|
+
if (hasCompleted && completedAt && !existingRow.completed_at) {
|
|
24693
|
+
assignments.push("completed_at = ?");
|
|
24694
|
+
values2.push(completedAt);
|
|
24695
|
+
}
|
|
24696
|
+
if (hasHash) {
|
|
24697
|
+
assignments.push("content_hash = ?");
|
|
24698
|
+
values2.push(hashTranscript2(mergedContent));
|
|
24699
|
+
}
|
|
24700
|
+
values2.push(agentId, candidate.sessionKey);
|
|
24701
|
+
db.prepare(`UPDATE session_transcripts SET ${assignments.join(", ")} WHERE agent_id = ? AND session_key = ?`).run(...values2);
|
|
24702
|
+
continue;
|
|
24703
|
+
}
|
|
24704
|
+
const values = [
|
|
24705
|
+
candidate.sessionKey,
|
|
24706
|
+
candidate.content,
|
|
24707
|
+
job.harness ?? null,
|
|
24708
|
+
job.project ?? null,
|
|
24709
|
+
agentId,
|
|
24710
|
+
candidate.createdAt
|
|
24711
|
+
];
|
|
24712
|
+
if (hasUpdated)
|
|
24713
|
+
values.push(candidate.createdAt);
|
|
24714
|
+
if (hasCompleted)
|
|
24715
|
+
values.push(candidate.completedAt);
|
|
24716
|
+
if (hasHash)
|
|
24717
|
+
values.push(hashTranscript2(candidate.content));
|
|
24718
|
+
insert.run(...values);
|
|
24719
|
+
}
|
|
24720
|
+
}
|
|
24721
|
+
function up1172(db) {
|
|
24722
|
+
if (!hasTable42(db, "session_transcripts"))
|
|
24723
|
+
return;
|
|
24724
|
+
addColumnIfMissing252(db, "session_transcripts", "completed_at", "TEXT");
|
|
24725
|
+
addColumnIfMissing252(db, "session_transcripts", "content_hash", "TEXT");
|
|
24726
|
+
backfillTranscriptHashes2(db);
|
|
24727
|
+
if (hasTable42(db, "transcript_capture_jobs")) {
|
|
24728
|
+
const captureColumns = db.prepare("PRAGMA table_info(transcript_capture_jobs)").all();
|
|
24729
|
+
if (captureColumns.some((row) => row.name === "summary_status")) {
|
|
24730
|
+
db.exec("UPDATE transcript_capture_jobs SET summary_status = 'not_requested' WHERE summary_status IN ('pending', 'failed', 'skipped')");
|
|
24731
|
+
}
|
|
24732
|
+
}
|
|
24733
|
+
if (hasTable42(db, "summary_jobs")) {
|
|
24734
|
+
backfillTranscriptsFromSummaryJobs2(db);
|
|
24735
|
+
backfillTranscriptHashes2(db);
|
|
24736
|
+
const summaryColumns = tableColumns2(db, "summary_jobs");
|
|
24737
|
+
const timestampParts = ["completed_at", "ended_at", "captured_at", "created_at"].filter((column) => summaryColumns.has(column)).map((column) => `sj.${column}`);
|
|
24738
|
+
const timestampValue = timestampParts.length === 1 ? timestampParts[0] : `COALESCE(${timestampParts.join(", ")})`;
|
|
24739
|
+
const completionTimestamp = timestampValue ? `MAX(${timestampValue})` : "NULL";
|
|
24740
|
+
const boundaryParts = [
|
|
24741
|
+
summaryColumns.has("trigger") ? "sj.trigger = 'session_end'" : null,
|
|
24742
|
+
summaryColumns.has("boundary_reason") ? "sj.boundary_reason IN ('session_closed', 'session_clear', 'stale_session', 'ttl_expired')" : null
|
|
24743
|
+
].filter((part) => part !== null);
|
|
24744
|
+
const boundaryPredicate = boundaryParts.length > 0 ? `(${boundaryParts.join(" OR ")})` : "1=1";
|
|
24745
|
+
const agentPredicate = summaryColumns.has("agent_id") ? "sj.agent_id = session_transcripts.agent_id" : "session_transcripts.agent_id = 'default'";
|
|
24746
|
+
if (completionTimestamp !== "NULL") {
|
|
24747
|
+
db.exec(`
|
|
24748
|
+
UPDATE session_transcripts
|
|
24749
|
+
SET completed_at = COALESCE(
|
|
24750
|
+
completed_at,
|
|
24751
|
+
(
|
|
24752
|
+
SELECT ${completionTimestamp}
|
|
24753
|
+
FROM summary_jobs AS sj
|
|
24754
|
+
WHERE ${agentPredicate}
|
|
24755
|
+
AND sj.session_key = session_transcripts.session_key
|
|
24756
|
+
AND ${boundaryPredicate}
|
|
24757
|
+
)
|
|
24758
|
+
)
|
|
24759
|
+
WHERE completed_at IS NULL;
|
|
24760
|
+
`);
|
|
24761
|
+
}
|
|
24762
|
+
db.exec("DELETE FROM summary_jobs");
|
|
24763
|
+
}
|
|
24764
|
+
const completionIndexColumns = ["agent_id", "completed_at"];
|
|
24765
|
+
if (tableColumns2(db, "session_transcripts").has("updated_at"))
|
|
24766
|
+
completionIndexColumns.push("updated_at");
|
|
24767
|
+
db.exec(`
|
|
24768
|
+
CREATE INDEX IF NOT EXISTS idx_st_agent_completed
|
|
24769
|
+
ON session_transcripts(${completionIndexColumns.join(", ")});
|
|
24770
|
+
CREATE INDEX IF NOT EXISTS idx_st_agent_hash
|
|
24771
|
+
ON session_transcripts(agent_id, content_hash);
|
|
24772
|
+
`);
|
|
24773
|
+
}
|
|
24325
24774
|
var MIGRATIONS2 = [
|
|
24326
24775
|
{
|
|
24327
24776
|
version: 1,
|
|
24328
24777
|
name: "baseline",
|
|
24329
|
-
up:
|
|
24778
|
+
up: up118,
|
|
24330
24779
|
artifacts: { tables: ["memories", "conversations", "embeddings"] }
|
|
24331
24780
|
},
|
|
24332
24781
|
{
|
|
@@ -24392,7 +24841,7 @@ var MIGRATIONS2 = [
|
|
|
24392
24841
|
{
|
|
24393
24842
|
version: 11,
|
|
24394
24843
|
name: "session-scores",
|
|
24395
|
-
up:
|
|
24844
|
+
up: up119,
|
|
24396
24845
|
artifacts: { tables: ["session_scores"] }
|
|
24397
24846
|
},
|
|
24398
24847
|
{
|
|
@@ -25261,6 +25710,17 @@ var MIGRATIONS2 = [
|
|
|
25261
25710
|
{ table: "cross_agent_messages", column: "acp_target_agent_name" }
|
|
25262
25711
|
]
|
|
25263
25712
|
}
|
|
25713
|
+
},
|
|
25714
|
+
{
|
|
25715
|
+
version: 117,
|
|
25716
|
+
name: "retire-summary-worker",
|
|
25717
|
+
up: up1172,
|
|
25718
|
+
artifacts: {
|
|
25719
|
+
columns: [
|
|
25720
|
+
{ table: "session_transcripts", column: "completed_at" },
|
|
25721
|
+
{ table: "session_transcripts", column: "content_hash" }
|
|
25722
|
+
]
|
|
25723
|
+
}
|
|
25264
25724
|
}
|
|
25265
25725
|
];
|
|
25266
25726
|
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.185.
|
|
3
|
+
"version": "0.185.5",
|
|
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.185.
|
|
29
|
-
"@signetai/core": "0.185.
|
|
28
|
+
"@signetai/connector-base": "0.185.5",
|
|
29
|
+
"@signetai/core": "0.185.5"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/node": "^22.0.0",
|