@signetai/connector-forge 0.185.4 → 0.185.6
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 +527 -25
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ import { dirname as dirname5, isAbsolute, join as join3, relative, sep } from "n
|
|
|
21
21
|
import { createRequire } from "node:module";
|
|
22
22
|
import { dirname, join } from "node:path";
|
|
23
23
|
import { fileURLToPath } from "node:url";
|
|
24
|
+
import { createHash } from "node:crypto";
|
|
24
25
|
import { homedir as homedir2 } from "os";
|
|
25
26
|
import { join as join2 } from "path";
|
|
26
27
|
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync3, rmSync, statSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
@@ -10557,6 +10558,240 @@ function up116(db) {
|
|
|
10557
10558
|
ON cross_agent_messages(delivery_path, delivery_state, delivery_lease_expires_at, delivery_updated_at);
|
|
10558
10559
|
`);
|
|
10559
10560
|
}
|
|
10561
|
+
function hasTable4(db, table) {
|
|
10562
|
+
return db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
10563
|
+
}
|
|
10564
|
+
function addColumnIfMissing25(db, table, column, definition) {
|
|
10565
|
+
const columns = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
10566
|
+
if (columns.some((row) => row.name === column))
|
|
10567
|
+
return;
|
|
10568
|
+
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
10569
|
+
}
|
|
10570
|
+
function tableColumns(db, table) {
|
|
10571
|
+
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
10572
|
+
return new Set(rows.map((row) => typeof row.name === "string" ? row.name : ""));
|
|
10573
|
+
}
|
|
10574
|
+
function hashTranscript(content) {
|
|
10575
|
+
return createHash("sha256").update(content, "utf8").digest("hex");
|
|
10576
|
+
}
|
|
10577
|
+
function backfillTranscriptHashes(db) {
|
|
10578
|
+
const columns = tableColumns(db, "session_transcripts");
|
|
10579
|
+
if (!columns.has("content_hash") || !columns.has("content"))
|
|
10580
|
+
return;
|
|
10581
|
+
const rows = db.prepare("SELECT session_key, agent_id, content FROM session_transcripts WHERE content_hash IS NULL").all();
|
|
10582
|
+
const update = db.prepare("UPDATE session_transcripts SET content_hash = ? WHERE agent_id = ? AND session_key = ? AND content_hash IS NULL");
|
|
10583
|
+
for (const row of rows) {
|
|
10584
|
+
if (typeof row.content !== "string" || typeof row.session_key !== "string")
|
|
10585
|
+
continue;
|
|
10586
|
+
update.run(hashTranscript(row.content), typeof row.agent_id === "string" ? row.agent_id : "default", row.session_key);
|
|
10587
|
+
}
|
|
10588
|
+
}
|
|
10589
|
+
var COMPLETION_BOUNDARY_REASONS = new Set(["session_closed", "session_clear", "stale_session", "ttl_expired"]);
|
|
10590
|
+
function summaryJobTimestamp(job) {
|
|
10591
|
+
return job.completed_at ?? job.ended_at ?? job.captured_at ?? job.created_at ?? new Date(0).toISOString();
|
|
10592
|
+
}
|
|
10593
|
+
function laterTimestamp(current, candidate) {
|
|
10594
|
+
if (current === null)
|
|
10595
|
+
return candidate;
|
|
10596
|
+
if (candidate === null)
|
|
10597
|
+
return current;
|
|
10598
|
+
const currentMillis = Date.parse(current);
|
|
10599
|
+
const candidateMillis = Date.parse(candidate);
|
|
10600
|
+
if (Number.isFinite(currentMillis) && Number.isFinite(candidateMillis)) {
|
|
10601
|
+
return candidateMillis > currentMillis ? candidate : current;
|
|
10602
|
+
}
|
|
10603
|
+
return candidate > current ? candidate : current;
|
|
10604
|
+
}
|
|
10605
|
+
function isCompletionBoundary(job, columns) {
|
|
10606
|
+
return columns.has("trigger") && job.trigger === "session_end" || columns.has("boundary_reason") && COMPLETION_BOUNDARY_REASONS.has(job.boundary_reason ?? "");
|
|
10607
|
+
}
|
|
10608
|
+
function mergeTranscriptContent(current, next) {
|
|
10609
|
+
if (current.length === 0)
|
|
10610
|
+
return next;
|
|
10611
|
+
if (next.length === 0 || current === next || current.includes(next))
|
|
10612
|
+
return current;
|
|
10613
|
+
if (next.includes(current))
|
|
10614
|
+
return next;
|
|
10615
|
+
return `${current}
|
|
10616
|
+
${next}`;
|
|
10617
|
+
}
|
|
10618
|
+
function backfillTranscriptsFromSummaryJobs(db) {
|
|
10619
|
+
if (!hasTable4(db, "summary_jobs"))
|
|
10620
|
+
return;
|
|
10621
|
+
const summaryColumns = tableColumns(db, "summary_jobs");
|
|
10622
|
+
if (!summaryColumns.has("transcript"))
|
|
10623
|
+
return;
|
|
10624
|
+
const select = (name) => summaryColumns.has(name) ? `"${name}" AS "${name}"` : `NULL AS "${name}"`;
|
|
10625
|
+
const jobs = db.prepare(`SELECT ${[
|
|
10626
|
+
"id",
|
|
10627
|
+
"session_key",
|
|
10628
|
+
"transcript",
|
|
10629
|
+
"harness",
|
|
10630
|
+
"project",
|
|
10631
|
+
"agent_id",
|
|
10632
|
+
"trigger",
|
|
10633
|
+
"boundary_reason",
|
|
10634
|
+
"captured_at",
|
|
10635
|
+
"ended_at",
|
|
10636
|
+
"completed_at",
|
|
10637
|
+
"created_at"
|
|
10638
|
+
].map(select).join(", ")} FROM summary_jobs`).all();
|
|
10639
|
+
const candidates = new Map;
|
|
10640
|
+
for (const job of jobs) {
|
|
10641
|
+
if (typeof job.transcript !== "string" || job.transcript.trim().length === 0)
|
|
10642
|
+
continue;
|
|
10643
|
+
const agentId = typeof job.agent_id === "string" && job.agent_id.length > 0 ? job.agent_id : "default";
|
|
10644
|
+
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}`)}`;
|
|
10645
|
+
const key = `${agentId}\x00${sessionKey}`;
|
|
10646
|
+
const current = candidates.get(key);
|
|
10647
|
+
const timestamp = summaryJobTimestamp(job);
|
|
10648
|
+
const boundary = isCompletionBoundary(job, summaryColumns);
|
|
10649
|
+
const createdAt = job.captured_at ?? job.created_at ?? job.ended_at ?? timestamp;
|
|
10650
|
+
if (!current) {
|
|
10651
|
+
candidates.set(key, {
|
|
10652
|
+
sessionKey,
|
|
10653
|
+
job: { ...job, agent_id: agentId },
|
|
10654
|
+
content: job.transcript,
|
|
10655
|
+
createdAt,
|
|
10656
|
+
completedAt: boundary ? timestamp : null
|
|
10657
|
+
});
|
|
10658
|
+
continue;
|
|
10659
|
+
}
|
|
10660
|
+
const currentTimestamp = summaryJobTimestamp(current.job);
|
|
10661
|
+
const preferred = timestamp > currentTimestamp || timestamp === currentTimestamp && job.transcript.length > current.content.length ? { ...job, agent_id: agentId } : current.job;
|
|
10662
|
+
candidates.set(key, {
|
|
10663
|
+
sessionKey,
|
|
10664
|
+
job: preferred,
|
|
10665
|
+
content: mergeTranscriptContent(current.content, job.transcript),
|
|
10666
|
+
createdAt: current.createdAt < createdAt ? current.createdAt : createdAt,
|
|
10667
|
+
completedAt: laterTimestamp(current.completedAt, boundary ? timestamp : null)
|
|
10668
|
+
});
|
|
10669
|
+
}
|
|
10670
|
+
const transcriptColumns = tableColumns(db, "session_transcripts");
|
|
10671
|
+
const hasUpdated = transcriptColumns.has("updated_at");
|
|
10672
|
+
const hasCompleted = transcriptColumns.has("completed_at");
|
|
10673
|
+
const hasHash = transcriptColumns.has("content_hash");
|
|
10674
|
+
const insertColumns = ["session_key", "content", "harness", "project", "agent_id", "created_at"];
|
|
10675
|
+
if (hasUpdated)
|
|
10676
|
+
insertColumns.push("updated_at");
|
|
10677
|
+
if (hasCompleted)
|
|
10678
|
+
insertColumns.push("completed_at");
|
|
10679
|
+
if (hasHash)
|
|
10680
|
+
insertColumns.push("content_hash");
|
|
10681
|
+
const insert = db.prepare(`INSERT OR IGNORE INTO session_transcripts (${insertColumns.join(", ")}) VALUES (${insertColumns.map(() => "?").join(", ")})`);
|
|
10682
|
+
const existing = db.prepare("SELECT content, completed_at FROM session_transcripts WHERE agent_id = ? AND session_key = ?");
|
|
10683
|
+
for (const candidate of candidates.values()) {
|
|
10684
|
+
const job = candidate.job;
|
|
10685
|
+
const agentId = job.agent_id ?? "default";
|
|
10686
|
+
const existingRow = existing.get(agentId, candidate.sessionKey);
|
|
10687
|
+
if (existingRow != null) {
|
|
10688
|
+
const previousContent = typeof existingRow.content === "string" ? existingRow.content : "";
|
|
10689
|
+
const mergedContent = mergeTranscriptContent(previousContent, candidate.content);
|
|
10690
|
+
const completedAt = typeof existingRow.completed_at === "string" && existingRow.completed_at.length > 0 ? existingRow.completed_at : candidate.completedAt;
|
|
10691
|
+
const assignments = ["content = ?"];
|
|
10692
|
+
const values2 = [mergedContent];
|
|
10693
|
+
if (hasUpdated && mergedContent !== previousContent) {
|
|
10694
|
+
assignments.push("updated_at = ?");
|
|
10695
|
+
values2.push(candidate.createdAt);
|
|
10696
|
+
}
|
|
10697
|
+
if (hasCompleted && completedAt && !existingRow.completed_at) {
|
|
10698
|
+
assignments.push("completed_at = ?");
|
|
10699
|
+
values2.push(completedAt);
|
|
10700
|
+
}
|
|
10701
|
+
if (hasHash) {
|
|
10702
|
+
assignments.push("content_hash = ?");
|
|
10703
|
+
values2.push(hashTranscript(mergedContent));
|
|
10704
|
+
}
|
|
10705
|
+
values2.push(agentId, candidate.sessionKey);
|
|
10706
|
+
db.prepare(`UPDATE session_transcripts SET ${assignments.join(", ")} WHERE agent_id = ? AND session_key = ?`).run(...values2);
|
|
10707
|
+
continue;
|
|
10708
|
+
}
|
|
10709
|
+
const values = [
|
|
10710
|
+
candidate.sessionKey,
|
|
10711
|
+
candidate.content,
|
|
10712
|
+
job.harness ?? null,
|
|
10713
|
+
job.project ?? null,
|
|
10714
|
+
agentId,
|
|
10715
|
+
candidate.createdAt
|
|
10716
|
+
];
|
|
10717
|
+
if (hasUpdated)
|
|
10718
|
+
values.push(candidate.createdAt);
|
|
10719
|
+
if (hasCompleted)
|
|
10720
|
+
values.push(candidate.completedAt);
|
|
10721
|
+
if (hasHash)
|
|
10722
|
+
values.push(hashTranscript(candidate.content));
|
|
10723
|
+
insert.run(...values);
|
|
10724
|
+
}
|
|
10725
|
+
}
|
|
10726
|
+
function up117(db) {
|
|
10727
|
+
if (!hasTable4(db, "session_transcripts"))
|
|
10728
|
+
return;
|
|
10729
|
+
addColumnIfMissing25(db, "session_transcripts", "completed_at", "TEXT");
|
|
10730
|
+
addColumnIfMissing25(db, "session_transcripts", "content_hash", "TEXT");
|
|
10731
|
+
backfillTranscriptHashes(db);
|
|
10732
|
+
if (hasTable4(db, "transcript_capture_jobs")) {
|
|
10733
|
+
const captureColumns = db.prepare("PRAGMA table_info(transcript_capture_jobs)").all();
|
|
10734
|
+
if (captureColumns.some((row) => row.name === "summary_status")) {
|
|
10735
|
+
db.exec("UPDATE transcript_capture_jobs SET summary_status = 'not_requested' WHERE summary_status IN ('pending', 'failed', 'skipped')");
|
|
10736
|
+
}
|
|
10737
|
+
}
|
|
10738
|
+
if (hasTable4(db, "summary_jobs")) {
|
|
10739
|
+
backfillTranscriptsFromSummaryJobs(db);
|
|
10740
|
+
backfillTranscriptHashes(db);
|
|
10741
|
+
const summaryColumns = tableColumns(db, "summary_jobs");
|
|
10742
|
+
const timestampParts = ["completed_at", "ended_at", "captured_at", "created_at"].filter((column) => summaryColumns.has(column)).map((column) => `sj.${column}`);
|
|
10743
|
+
const timestampValue = timestampParts.length === 1 ? timestampParts[0] : `COALESCE(${timestampParts.join(", ")})`;
|
|
10744
|
+
const completionTimestamp = timestampValue ? `MAX(${timestampValue})` : "NULL";
|
|
10745
|
+
const boundaryParts = [
|
|
10746
|
+
summaryColumns.has("trigger") ? "sj.trigger = 'session_end'" : null,
|
|
10747
|
+
summaryColumns.has("boundary_reason") ? "sj.boundary_reason IN ('session_closed', 'session_clear', 'stale_session', 'ttl_expired')" : null
|
|
10748
|
+
].filter((part) => part !== null);
|
|
10749
|
+
const boundaryPredicate = boundaryParts.length > 0 ? `(${boundaryParts.join(" OR ")})` : "1=1";
|
|
10750
|
+
const agentPredicate = summaryColumns.has("agent_id") ? "sj.agent_id = session_transcripts.agent_id" : "session_transcripts.agent_id = 'default'";
|
|
10751
|
+
if (completionTimestamp !== "NULL") {
|
|
10752
|
+
db.exec(`
|
|
10753
|
+
UPDATE session_transcripts
|
|
10754
|
+
SET completed_at = COALESCE(
|
|
10755
|
+
completed_at,
|
|
10756
|
+
(
|
|
10757
|
+
SELECT ${completionTimestamp}
|
|
10758
|
+
FROM summary_jobs AS sj
|
|
10759
|
+
WHERE ${agentPredicate}
|
|
10760
|
+
AND sj.session_key = session_transcripts.session_key
|
|
10761
|
+
AND ${boundaryPredicate}
|
|
10762
|
+
)
|
|
10763
|
+
)
|
|
10764
|
+
WHERE completed_at IS NULL;
|
|
10765
|
+
`);
|
|
10766
|
+
}
|
|
10767
|
+
db.exec("DELETE FROM summary_jobs");
|
|
10768
|
+
}
|
|
10769
|
+
const completionIndexColumns = ["agent_id", "completed_at"];
|
|
10770
|
+
if (tableColumns(db, "session_transcripts").has("updated_at"))
|
|
10771
|
+
completionIndexColumns.push("updated_at");
|
|
10772
|
+
db.exec(`
|
|
10773
|
+
CREATE INDEX IF NOT EXISTS idx_st_agent_completed
|
|
10774
|
+
ON session_transcripts(${completionIndexColumns.join(", ")});
|
|
10775
|
+
CREATE INDEX IF NOT EXISTS idx_st_agent_hash
|
|
10776
|
+
ON session_transcripts(agent_id, content_hash);
|
|
10777
|
+
`);
|
|
10778
|
+
}
|
|
10779
|
+
function up118(db) {
|
|
10780
|
+
db.exec(`
|
|
10781
|
+
CREATE INDEX IF NOT EXISTS idx_memory_jobs_pressure_status
|
|
10782
|
+
ON memory_jobs(status)
|
|
10783
|
+
WHERE status IN ('pending', 'leased') AND job_type <> 'extract';
|
|
10784
|
+
CREATE INDEX IF NOT EXISTS idx_memory_jobs_pressure_created_at
|
|
10785
|
+
ON memory_jobs(created_at)
|
|
10786
|
+
WHERE status IN ('pending', 'leased') AND job_type <> 'extract';
|
|
10787
|
+
CREATE INDEX IF NOT EXISTS idx_summary_jobs_pressure_status
|
|
10788
|
+
ON summary_jobs(status)
|
|
10789
|
+
WHERE status IN ('pending', 'leased');
|
|
10790
|
+
CREATE INDEX IF NOT EXISTS idx_summary_jobs_pressure_created_at
|
|
10791
|
+
ON summary_jobs(created_at)
|
|
10792
|
+
WHERE status IN ('pending', 'leased');
|
|
10793
|
+
`);
|
|
10794
|
+
}
|
|
10560
10795
|
var MIGRATIONS = [
|
|
10561
10796
|
{
|
|
10562
10797
|
version: 1,
|
|
@@ -11496,6 +11731,22 @@ var MIGRATIONS = [
|
|
|
11496
11731
|
{ table: "cross_agent_messages", column: "acp_target_agent_name" }
|
|
11497
11732
|
]
|
|
11498
11733
|
}
|
|
11734
|
+
},
|
|
11735
|
+
{
|
|
11736
|
+
version: 117,
|
|
11737
|
+
name: "retire-summary-worker",
|
|
11738
|
+
up: up117,
|
|
11739
|
+
artifacts: {
|
|
11740
|
+
columns: [
|
|
11741
|
+
{ table: "session_transcripts", column: "completed_at" },
|
|
11742
|
+
{ table: "session_transcripts", column: "content_hash" }
|
|
11743
|
+
]
|
|
11744
|
+
}
|
|
11745
|
+
},
|
|
11746
|
+
{
|
|
11747
|
+
version: 118,
|
|
11748
|
+
name: "queue-pressure-indices",
|
|
11749
|
+
up: up118
|
|
11499
11750
|
}
|
|
11500
11751
|
];
|
|
11501
11752
|
var LATEST_SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0;
|
|
@@ -12060,6 +12311,7 @@ function resolveRemoteDaemonUrl() {
|
|
|
12060
12311
|
import { createRequire as createRequire3 } from "node:module";
|
|
12061
12312
|
import { dirname as dirname6, join as join4 } from "node:path";
|
|
12062
12313
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
12314
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
12063
12315
|
import { homedir as homedir22 } from "os";
|
|
12064
12316
|
import { join as join22 } from "path";
|
|
12065
12317
|
import { createRequire as createRequire22 } from "node:module";
|
|
@@ -19017,7 +19269,7 @@ function memoriesFtsNeedsTokenizerRepair2(sql) {
|
|
|
19017
19269
|
return true;
|
|
19018
19270
|
return !normalized.includes(`tokenize='${MEMORIES_FTS_TOKENIZER2}'`);
|
|
19019
19271
|
}
|
|
19020
|
-
function
|
|
19272
|
+
function up119(db) {
|
|
19021
19273
|
db.exec(`
|
|
19022
19274
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
19023
19275
|
version INTEGER PRIMARY KEY,
|
|
@@ -19110,27 +19362,27 @@ function hasColumn22(db, table, column) {
|
|
|
19110
19362
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
19111
19363
|
return rows.some((r) => r.name === column);
|
|
19112
19364
|
}
|
|
19113
|
-
function
|
|
19365
|
+
function addColumnIfMissing26(db, table, column, definition) {
|
|
19114
19366
|
if (!hasColumn22(db, table, column)) {
|
|
19115
19367
|
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
19116
19368
|
}
|
|
19117
19369
|
}
|
|
19118
19370
|
function up210(db) {
|
|
19119
|
-
|
|
19120
|
-
|
|
19121
|
-
|
|
19122
|
-
|
|
19123
|
-
|
|
19124
|
-
|
|
19125
|
-
|
|
19126
|
-
|
|
19127
|
-
|
|
19128
|
-
|
|
19129
|
-
|
|
19130
|
-
|
|
19131
|
-
|
|
19132
|
-
|
|
19133
|
-
|
|
19371
|
+
addColumnIfMissing26(db, "memories", "content_hash", "TEXT");
|
|
19372
|
+
addColumnIfMissing26(db, "memories", "normalized_content", "TEXT");
|
|
19373
|
+
addColumnIfMissing26(db, "memories", "is_deleted", "INTEGER DEFAULT 0");
|
|
19374
|
+
addColumnIfMissing26(db, "memories", "deleted_at", "TEXT");
|
|
19375
|
+
addColumnIfMissing26(db, "memories", "extraction_status", "TEXT DEFAULT 'none'");
|
|
19376
|
+
addColumnIfMissing26(db, "memories", "embedding_model", "TEXT");
|
|
19377
|
+
addColumnIfMissing26(db, "memories", "extraction_model", "TEXT");
|
|
19378
|
+
addColumnIfMissing26(db, "memories", "update_count", "INTEGER DEFAULT 0");
|
|
19379
|
+
addColumnIfMissing26(db, "memories", "who", "TEXT");
|
|
19380
|
+
addColumnIfMissing26(db, "memories", "why", "TEXT");
|
|
19381
|
+
addColumnIfMissing26(db, "memories", "project", "TEXT");
|
|
19382
|
+
addColumnIfMissing26(db, "memories", "pinned", "INTEGER DEFAULT 0");
|
|
19383
|
+
addColumnIfMissing26(db, "memories", "importance", "REAL DEFAULT 0.5");
|
|
19384
|
+
addColumnIfMissing26(db, "memories", "last_accessed", "TEXT");
|
|
19385
|
+
addColumnIfMissing26(db, "memories", "access_count", "INTEGER DEFAULT 0");
|
|
19134
19386
|
db.exec(`
|
|
19135
19387
|
CREATE TABLE IF NOT EXISTS memory_history (
|
|
19136
19388
|
id TEXT PRIMARY KEY,
|
|
@@ -19226,7 +19478,7 @@ function up210(db) {
|
|
|
19226
19478
|
ON memory_entity_mentions(entity_id);
|
|
19227
19479
|
`);
|
|
19228
19480
|
}
|
|
19229
|
-
function
|
|
19481
|
+
function addColumnIfMissing27(db, table, column, definition) {
|
|
19230
19482
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
19231
19483
|
if (rows.some((r) => r.name === column))
|
|
19232
19484
|
return false;
|
|
@@ -19234,8 +19486,8 @@ function addColumnIfMissing26(db, table, column, definition) {
|
|
|
19234
19486
|
return true;
|
|
19235
19487
|
}
|
|
19236
19488
|
function up310(db) {
|
|
19237
|
-
|
|
19238
|
-
|
|
19489
|
+
addColumnIfMissing27(db, "memories", "why", "TEXT");
|
|
19490
|
+
addColumnIfMissing27(db, "memories", "project", "TEXT");
|
|
19239
19491
|
db.exec(`DROP INDEX IF EXISTS idx_memories_content_hash`);
|
|
19240
19492
|
db.exec(`
|
|
19241
19493
|
UPDATE memories
|
|
@@ -19440,7 +19692,7 @@ function up1010(db) {
|
|
|
19440
19692
|
)
|
|
19441
19693
|
`);
|
|
19442
19694
|
}
|
|
19443
|
-
function
|
|
19695
|
+
function up1110(db) {
|
|
19444
19696
|
db.exec(`
|
|
19445
19697
|
CREATE TABLE IF NOT EXISTS session_scores (
|
|
19446
19698
|
id TEXT PRIMARY KEY,
|
|
@@ -20661,7 +20913,7 @@ function up492(db) {
|
|
|
20661
20913
|
);
|
|
20662
20914
|
`);
|
|
20663
20915
|
}
|
|
20664
|
-
function
|
|
20916
|
+
function hasTable5(db, name) {
|
|
20665
20917
|
return db.prepare(`SELECT name
|
|
20666
20918
|
FROM sqlite_master
|
|
20667
20919
|
WHERE type = 'table' AND name = ?
|
|
@@ -20691,7 +20943,7 @@ function up502(db) {
|
|
|
20691
20943
|
CREATE INDEX IF NOT EXISTS idx_entity_dependency_history_created
|
|
20692
20944
|
ON entity_dependency_history(created_at DESC);
|
|
20693
20945
|
`);
|
|
20694
|
-
if (!
|
|
20946
|
+
if (!hasTable5(db, "entity_dependencies"))
|
|
20695
20947
|
return;
|
|
20696
20948
|
db.exec("DROP TRIGGER IF EXISTS trg_entity_dependencies_related_to_reason_insert");
|
|
20697
20949
|
db.exec("DROP TRIGGER IF EXISTS trg_entity_dependencies_related_to_reason_update");
|
|
@@ -22593,11 +22845,245 @@ function up1162(db) {
|
|
|
22593
22845
|
ON cross_agent_messages(delivery_path, delivery_state, delivery_lease_expires_at, delivery_updated_at);
|
|
22594
22846
|
`);
|
|
22595
22847
|
}
|
|
22848
|
+
function hasTable42(db, table) {
|
|
22849
|
+
return db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
22850
|
+
}
|
|
22851
|
+
function addColumnIfMissing252(db, table, column, definition) {
|
|
22852
|
+
const columns = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
22853
|
+
if (columns.some((row) => row.name === column))
|
|
22854
|
+
return;
|
|
22855
|
+
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
22856
|
+
}
|
|
22857
|
+
function tableColumns2(db, table) {
|
|
22858
|
+
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
22859
|
+
return new Set(rows.map((row) => typeof row.name === "string" ? row.name : ""));
|
|
22860
|
+
}
|
|
22861
|
+
function hashTranscript2(content) {
|
|
22862
|
+
return createHash2("sha256").update(content, "utf8").digest("hex");
|
|
22863
|
+
}
|
|
22864
|
+
function backfillTranscriptHashes2(db) {
|
|
22865
|
+
const columns = tableColumns2(db, "session_transcripts");
|
|
22866
|
+
if (!columns.has("content_hash") || !columns.has("content"))
|
|
22867
|
+
return;
|
|
22868
|
+
const rows = db.prepare("SELECT session_key, agent_id, content FROM session_transcripts WHERE content_hash IS NULL").all();
|
|
22869
|
+
const update = db.prepare("UPDATE session_transcripts SET content_hash = ? WHERE agent_id = ? AND session_key = ? AND content_hash IS NULL");
|
|
22870
|
+
for (const row of rows) {
|
|
22871
|
+
if (typeof row.content !== "string" || typeof row.session_key !== "string")
|
|
22872
|
+
continue;
|
|
22873
|
+
update.run(hashTranscript2(row.content), typeof row.agent_id === "string" ? row.agent_id : "default", row.session_key);
|
|
22874
|
+
}
|
|
22875
|
+
}
|
|
22876
|
+
var COMPLETION_BOUNDARY_REASONS2 = new Set(["session_closed", "session_clear", "stale_session", "ttl_expired"]);
|
|
22877
|
+
function summaryJobTimestamp2(job) {
|
|
22878
|
+
return job.completed_at ?? job.ended_at ?? job.captured_at ?? job.created_at ?? new Date(0).toISOString();
|
|
22879
|
+
}
|
|
22880
|
+
function laterTimestamp2(current, candidate) {
|
|
22881
|
+
if (current === null)
|
|
22882
|
+
return candidate;
|
|
22883
|
+
if (candidate === null)
|
|
22884
|
+
return current;
|
|
22885
|
+
const currentMillis = Date.parse(current);
|
|
22886
|
+
const candidateMillis = Date.parse(candidate);
|
|
22887
|
+
if (Number.isFinite(currentMillis) && Number.isFinite(candidateMillis)) {
|
|
22888
|
+
return candidateMillis > currentMillis ? candidate : current;
|
|
22889
|
+
}
|
|
22890
|
+
return candidate > current ? candidate : current;
|
|
22891
|
+
}
|
|
22892
|
+
function isCompletionBoundary2(job, columns) {
|
|
22893
|
+
return columns.has("trigger") && job.trigger === "session_end" || columns.has("boundary_reason") && COMPLETION_BOUNDARY_REASONS2.has(job.boundary_reason ?? "");
|
|
22894
|
+
}
|
|
22895
|
+
function mergeTranscriptContent2(current, next) {
|
|
22896
|
+
if (current.length === 0)
|
|
22897
|
+
return next;
|
|
22898
|
+
if (next.length === 0 || current === next || current.includes(next))
|
|
22899
|
+
return current;
|
|
22900
|
+
if (next.includes(current))
|
|
22901
|
+
return next;
|
|
22902
|
+
return `${current}
|
|
22903
|
+
${next}`;
|
|
22904
|
+
}
|
|
22905
|
+
function backfillTranscriptsFromSummaryJobs2(db) {
|
|
22906
|
+
if (!hasTable42(db, "summary_jobs"))
|
|
22907
|
+
return;
|
|
22908
|
+
const summaryColumns = tableColumns2(db, "summary_jobs");
|
|
22909
|
+
if (!summaryColumns.has("transcript"))
|
|
22910
|
+
return;
|
|
22911
|
+
const select = (name) => summaryColumns.has(name) ? `"${name}" AS "${name}"` : `NULL AS "${name}"`;
|
|
22912
|
+
const jobs = db.prepare(`SELECT ${[
|
|
22913
|
+
"id",
|
|
22914
|
+
"session_key",
|
|
22915
|
+
"transcript",
|
|
22916
|
+
"harness",
|
|
22917
|
+
"project",
|
|
22918
|
+
"agent_id",
|
|
22919
|
+
"trigger",
|
|
22920
|
+
"boundary_reason",
|
|
22921
|
+
"captured_at",
|
|
22922
|
+
"ended_at",
|
|
22923
|
+
"completed_at",
|
|
22924
|
+
"created_at"
|
|
22925
|
+
].map(select).join(", ")} FROM summary_jobs`).all();
|
|
22926
|
+
const candidates = new Map;
|
|
22927
|
+
for (const job of jobs) {
|
|
22928
|
+
if (typeof job.transcript !== "string" || job.transcript.trim().length === 0)
|
|
22929
|
+
continue;
|
|
22930
|
+
const agentId = typeof job.agent_id === "string" && job.agent_id.length > 0 ? job.agent_id : "default";
|
|
22931
|
+
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}`)}`;
|
|
22932
|
+
const key = `${agentId}\x00${sessionKey}`;
|
|
22933
|
+
const current = candidates.get(key);
|
|
22934
|
+
const timestamp = summaryJobTimestamp2(job);
|
|
22935
|
+
const boundary = isCompletionBoundary2(job, summaryColumns);
|
|
22936
|
+
const createdAt = job.captured_at ?? job.created_at ?? job.ended_at ?? timestamp;
|
|
22937
|
+
if (!current) {
|
|
22938
|
+
candidates.set(key, {
|
|
22939
|
+
sessionKey,
|
|
22940
|
+
job: { ...job, agent_id: agentId },
|
|
22941
|
+
content: job.transcript,
|
|
22942
|
+
createdAt,
|
|
22943
|
+
completedAt: boundary ? timestamp : null
|
|
22944
|
+
});
|
|
22945
|
+
continue;
|
|
22946
|
+
}
|
|
22947
|
+
const currentTimestamp = summaryJobTimestamp2(current.job);
|
|
22948
|
+
const preferred = timestamp > currentTimestamp || timestamp === currentTimestamp && job.transcript.length > current.content.length ? { ...job, agent_id: agentId } : current.job;
|
|
22949
|
+
candidates.set(key, {
|
|
22950
|
+
sessionKey,
|
|
22951
|
+
job: preferred,
|
|
22952
|
+
content: mergeTranscriptContent2(current.content, job.transcript),
|
|
22953
|
+
createdAt: current.createdAt < createdAt ? current.createdAt : createdAt,
|
|
22954
|
+
completedAt: laterTimestamp2(current.completedAt, boundary ? timestamp : null)
|
|
22955
|
+
});
|
|
22956
|
+
}
|
|
22957
|
+
const transcriptColumns = tableColumns2(db, "session_transcripts");
|
|
22958
|
+
const hasUpdated = transcriptColumns.has("updated_at");
|
|
22959
|
+
const hasCompleted = transcriptColumns.has("completed_at");
|
|
22960
|
+
const hasHash = transcriptColumns.has("content_hash");
|
|
22961
|
+
const insertColumns = ["session_key", "content", "harness", "project", "agent_id", "created_at"];
|
|
22962
|
+
if (hasUpdated)
|
|
22963
|
+
insertColumns.push("updated_at");
|
|
22964
|
+
if (hasCompleted)
|
|
22965
|
+
insertColumns.push("completed_at");
|
|
22966
|
+
if (hasHash)
|
|
22967
|
+
insertColumns.push("content_hash");
|
|
22968
|
+
const insert = db.prepare(`INSERT OR IGNORE INTO session_transcripts (${insertColumns.join(", ")}) VALUES (${insertColumns.map(() => "?").join(", ")})`);
|
|
22969
|
+
const existing = db.prepare("SELECT content, completed_at FROM session_transcripts WHERE agent_id = ? AND session_key = ?");
|
|
22970
|
+
for (const candidate of candidates.values()) {
|
|
22971
|
+
const job = candidate.job;
|
|
22972
|
+
const agentId = job.agent_id ?? "default";
|
|
22973
|
+
const existingRow = existing.get(agentId, candidate.sessionKey);
|
|
22974
|
+
if (existingRow != null) {
|
|
22975
|
+
const previousContent = typeof existingRow.content === "string" ? existingRow.content : "";
|
|
22976
|
+
const mergedContent = mergeTranscriptContent2(previousContent, candidate.content);
|
|
22977
|
+
const completedAt = typeof existingRow.completed_at === "string" && existingRow.completed_at.length > 0 ? existingRow.completed_at : candidate.completedAt;
|
|
22978
|
+
const assignments = ["content = ?"];
|
|
22979
|
+
const values2 = [mergedContent];
|
|
22980
|
+
if (hasUpdated && mergedContent !== previousContent) {
|
|
22981
|
+
assignments.push("updated_at = ?");
|
|
22982
|
+
values2.push(candidate.createdAt);
|
|
22983
|
+
}
|
|
22984
|
+
if (hasCompleted && completedAt && !existingRow.completed_at) {
|
|
22985
|
+
assignments.push("completed_at = ?");
|
|
22986
|
+
values2.push(completedAt);
|
|
22987
|
+
}
|
|
22988
|
+
if (hasHash) {
|
|
22989
|
+
assignments.push("content_hash = ?");
|
|
22990
|
+
values2.push(hashTranscript2(mergedContent));
|
|
22991
|
+
}
|
|
22992
|
+
values2.push(agentId, candidate.sessionKey);
|
|
22993
|
+
db.prepare(`UPDATE session_transcripts SET ${assignments.join(", ")} WHERE agent_id = ? AND session_key = ?`).run(...values2);
|
|
22994
|
+
continue;
|
|
22995
|
+
}
|
|
22996
|
+
const values = [
|
|
22997
|
+
candidate.sessionKey,
|
|
22998
|
+
candidate.content,
|
|
22999
|
+
job.harness ?? null,
|
|
23000
|
+
job.project ?? null,
|
|
23001
|
+
agentId,
|
|
23002
|
+
candidate.createdAt
|
|
23003
|
+
];
|
|
23004
|
+
if (hasUpdated)
|
|
23005
|
+
values.push(candidate.createdAt);
|
|
23006
|
+
if (hasCompleted)
|
|
23007
|
+
values.push(candidate.completedAt);
|
|
23008
|
+
if (hasHash)
|
|
23009
|
+
values.push(hashTranscript2(candidate.content));
|
|
23010
|
+
insert.run(...values);
|
|
23011
|
+
}
|
|
23012
|
+
}
|
|
23013
|
+
function up1172(db) {
|
|
23014
|
+
if (!hasTable42(db, "session_transcripts"))
|
|
23015
|
+
return;
|
|
23016
|
+
addColumnIfMissing252(db, "session_transcripts", "completed_at", "TEXT");
|
|
23017
|
+
addColumnIfMissing252(db, "session_transcripts", "content_hash", "TEXT");
|
|
23018
|
+
backfillTranscriptHashes2(db);
|
|
23019
|
+
if (hasTable42(db, "transcript_capture_jobs")) {
|
|
23020
|
+
const captureColumns = db.prepare("PRAGMA table_info(transcript_capture_jobs)").all();
|
|
23021
|
+
if (captureColumns.some((row) => row.name === "summary_status")) {
|
|
23022
|
+
db.exec("UPDATE transcript_capture_jobs SET summary_status = 'not_requested' WHERE summary_status IN ('pending', 'failed', 'skipped')");
|
|
23023
|
+
}
|
|
23024
|
+
}
|
|
23025
|
+
if (hasTable42(db, "summary_jobs")) {
|
|
23026
|
+
backfillTranscriptsFromSummaryJobs2(db);
|
|
23027
|
+
backfillTranscriptHashes2(db);
|
|
23028
|
+
const summaryColumns = tableColumns2(db, "summary_jobs");
|
|
23029
|
+
const timestampParts = ["completed_at", "ended_at", "captured_at", "created_at"].filter((column) => summaryColumns.has(column)).map((column) => `sj.${column}`);
|
|
23030
|
+
const timestampValue = timestampParts.length === 1 ? timestampParts[0] : `COALESCE(${timestampParts.join(", ")})`;
|
|
23031
|
+
const completionTimestamp = timestampValue ? `MAX(${timestampValue})` : "NULL";
|
|
23032
|
+
const boundaryParts = [
|
|
23033
|
+
summaryColumns.has("trigger") ? "sj.trigger = 'session_end'" : null,
|
|
23034
|
+
summaryColumns.has("boundary_reason") ? "sj.boundary_reason IN ('session_closed', 'session_clear', 'stale_session', 'ttl_expired')" : null
|
|
23035
|
+
].filter((part) => part !== null);
|
|
23036
|
+
const boundaryPredicate = boundaryParts.length > 0 ? `(${boundaryParts.join(" OR ")})` : "1=1";
|
|
23037
|
+
const agentPredicate = summaryColumns.has("agent_id") ? "sj.agent_id = session_transcripts.agent_id" : "session_transcripts.agent_id = 'default'";
|
|
23038
|
+
if (completionTimestamp !== "NULL") {
|
|
23039
|
+
db.exec(`
|
|
23040
|
+
UPDATE session_transcripts
|
|
23041
|
+
SET completed_at = COALESCE(
|
|
23042
|
+
completed_at,
|
|
23043
|
+
(
|
|
23044
|
+
SELECT ${completionTimestamp}
|
|
23045
|
+
FROM summary_jobs AS sj
|
|
23046
|
+
WHERE ${agentPredicate}
|
|
23047
|
+
AND sj.session_key = session_transcripts.session_key
|
|
23048
|
+
AND ${boundaryPredicate}
|
|
23049
|
+
)
|
|
23050
|
+
)
|
|
23051
|
+
WHERE completed_at IS NULL;
|
|
23052
|
+
`);
|
|
23053
|
+
}
|
|
23054
|
+
db.exec("DELETE FROM summary_jobs");
|
|
23055
|
+
}
|
|
23056
|
+
const completionIndexColumns = ["agent_id", "completed_at"];
|
|
23057
|
+
if (tableColumns2(db, "session_transcripts").has("updated_at"))
|
|
23058
|
+
completionIndexColumns.push("updated_at");
|
|
23059
|
+
db.exec(`
|
|
23060
|
+
CREATE INDEX IF NOT EXISTS idx_st_agent_completed
|
|
23061
|
+
ON session_transcripts(${completionIndexColumns.join(", ")});
|
|
23062
|
+
CREATE INDEX IF NOT EXISTS idx_st_agent_hash
|
|
23063
|
+
ON session_transcripts(agent_id, content_hash);
|
|
23064
|
+
`);
|
|
23065
|
+
}
|
|
23066
|
+
function up1182(db) {
|
|
23067
|
+
db.exec(`
|
|
23068
|
+
CREATE INDEX IF NOT EXISTS idx_memory_jobs_pressure_status
|
|
23069
|
+
ON memory_jobs(status)
|
|
23070
|
+
WHERE status IN ('pending', 'leased') AND job_type <> 'extract';
|
|
23071
|
+
CREATE INDEX IF NOT EXISTS idx_memory_jobs_pressure_created_at
|
|
23072
|
+
ON memory_jobs(created_at)
|
|
23073
|
+
WHERE status IN ('pending', 'leased') AND job_type <> 'extract';
|
|
23074
|
+
CREATE INDEX IF NOT EXISTS idx_summary_jobs_pressure_status
|
|
23075
|
+
ON summary_jobs(status)
|
|
23076
|
+
WHERE status IN ('pending', 'leased');
|
|
23077
|
+
CREATE INDEX IF NOT EXISTS idx_summary_jobs_pressure_created_at
|
|
23078
|
+
ON summary_jobs(created_at)
|
|
23079
|
+
WHERE status IN ('pending', 'leased');
|
|
23080
|
+
`);
|
|
23081
|
+
}
|
|
22596
23082
|
var MIGRATIONS2 = [
|
|
22597
23083
|
{
|
|
22598
23084
|
version: 1,
|
|
22599
23085
|
name: "baseline",
|
|
22600
|
-
up:
|
|
23086
|
+
up: up119,
|
|
22601
23087
|
artifacts: { tables: ["memories", "conversations", "embeddings"] }
|
|
22602
23088
|
},
|
|
22603
23089
|
{
|
|
@@ -22663,7 +23149,7 @@ var MIGRATIONS2 = [
|
|
|
22663
23149
|
{
|
|
22664
23150
|
version: 11,
|
|
22665
23151
|
name: "session-scores",
|
|
22666
|
-
up:
|
|
23152
|
+
up: up1110,
|
|
22667
23153
|
artifacts: { tables: ["session_scores"] }
|
|
22668
23154
|
},
|
|
22669
23155
|
{
|
|
@@ -23532,6 +24018,22 @@ var MIGRATIONS2 = [
|
|
|
23532
24018
|
{ table: "cross_agent_messages", column: "acp_target_agent_name" }
|
|
23533
24019
|
]
|
|
23534
24020
|
}
|
|
24021
|
+
},
|
|
24022
|
+
{
|
|
24023
|
+
version: 117,
|
|
24024
|
+
name: "retire-summary-worker",
|
|
24025
|
+
up: up1172,
|
|
24026
|
+
artifacts: {
|
|
24027
|
+
columns: [
|
|
24028
|
+
{ table: "session_transcripts", column: "completed_at" },
|
|
24029
|
+
{ table: "session_transcripts", column: "content_hash" }
|
|
24030
|
+
]
|
|
24031
|
+
}
|
|
24032
|
+
},
|
|
24033
|
+
{
|
|
24034
|
+
version: 118,
|
|
24035
|
+
name: "queue-pressure-indices",
|
|
24036
|
+
up: up1182
|
|
23535
24037
|
}
|
|
23536
24038
|
];
|
|
23537
24039
|
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.185.
|
|
3
|
+
"version": "0.185.6",
|
|
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.185.
|
|
28
|
-
"@signetai/core": "0.185.
|
|
27
|
+
"@signetai/connector-base": "0.185.6",
|
|
28
|
+
"@signetai/core": "0.185.6"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^22.0.0",
|