@signetai/connector-hermes-agent 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 +529 -27
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { spawnSync } from "node:child_process";
|
|
3
|
-
import { createHash } from "node:crypto";
|
|
3
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
4
4
|
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
6
|
import { dirname as dirname6, join as join4 } from "node:path";
|
|
@@ -13,6 +13,7 @@ import { dirname as dirname5, isAbsolute, join as join3, relative, sep } from "n
|
|
|
13
13
|
import { createRequire } from "node:module";
|
|
14
14
|
import { dirname, join } from "node:path";
|
|
15
15
|
import { fileURLToPath } from "node:url";
|
|
16
|
+
import { createHash } from "node:crypto";
|
|
16
17
|
import { createRequire as createRequire2 } from "node:module";
|
|
17
18
|
import { homedir as homedir4 } from "node:os";
|
|
18
19
|
import { dirname as dirname3, join as join6, resolve as resolve2 } from "node:path";
|
|
@@ -10544,6 +10545,240 @@ function up116(db) {
|
|
|
10544
10545
|
ON cross_agent_messages(delivery_path, delivery_state, delivery_lease_expires_at, delivery_updated_at);
|
|
10545
10546
|
`);
|
|
10546
10547
|
}
|
|
10548
|
+
function hasTable4(db, table) {
|
|
10549
|
+
return db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
10550
|
+
}
|
|
10551
|
+
function addColumnIfMissing25(db, table, column, definition) {
|
|
10552
|
+
const columns = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
10553
|
+
if (columns.some((row) => row.name === column))
|
|
10554
|
+
return;
|
|
10555
|
+
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
10556
|
+
}
|
|
10557
|
+
function tableColumns(db, table) {
|
|
10558
|
+
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
10559
|
+
return new Set(rows.map((row) => typeof row.name === "string" ? row.name : ""));
|
|
10560
|
+
}
|
|
10561
|
+
function hashTranscript(content) {
|
|
10562
|
+
return createHash("sha256").update(content, "utf8").digest("hex");
|
|
10563
|
+
}
|
|
10564
|
+
function backfillTranscriptHashes(db) {
|
|
10565
|
+
const columns = tableColumns(db, "session_transcripts");
|
|
10566
|
+
if (!columns.has("content_hash") || !columns.has("content"))
|
|
10567
|
+
return;
|
|
10568
|
+
const rows = db.prepare("SELECT session_key, agent_id, content FROM session_transcripts WHERE content_hash IS NULL").all();
|
|
10569
|
+
const update = db.prepare("UPDATE session_transcripts SET content_hash = ? WHERE agent_id = ? AND session_key = ? AND content_hash IS NULL");
|
|
10570
|
+
for (const row of rows) {
|
|
10571
|
+
if (typeof row.content !== "string" || typeof row.session_key !== "string")
|
|
10572
|
+
continue;
|
|
10573
|
+
update.run(hashTranscript(row.content), typeof row.agent_id === "string" ? row.agent_id : "default", row.session_key);
|
|
10574
|
+
}
|
|
10575
|
+
}
|
|
10576
|
+
var COMPLETION_BOUNDARY_REASONS = new Set(["session_closed", "session_clear", "stale_session", "ttl_expired"]);
|
|
10577
|
+
function summaryJobTimestamp(job) {
|
|
10578
|
+
return job.completed_at ?? job.ended_at ?? job.captured_at ?? job.created_at ?? new Date(0).toISOString();
|
|
10579
|
+
}
|
|
10580
|
+
function laterTimestamp(current, candidate) {
|
|
10581
|
+
if (current === null)
|
|
10582
|
+
return candidate;
|
|
10583
|
+
if (candidate === null)
|
|
10584
|
+
return current;
|
|
10585
|
+
const currentMillis = Date.parse(current);
|
|
10586
|
+
const candidateMillis = Date.parse(candidate);
|
|
10587
|
+
if (Number.isFinite(currentMillis) && Number.isFinite(candidateMillis)) {
|
|
10588
|
+
return candidateMillis > currentMillis ? candidate : current;
|
|
10589
|
+
}
|
|
10590
|
+
return candidate > current ? candidate : current;
|
|
10591
|
+
}
|
|
10592
|
+
function isCompletionBoundary(job, columns) {
|
|
10593
|
+
return columns.has("trigger") && job.trigger === "session_end" || columns.has("boundary_reason") && COMPLETION_BOUNDARY_REASONS.has(job.boundary_reason ?? "");
|
|
10594
|
+
}
|
|
10595
|
+
function mergeTranscriptContent(current, next) {
|
|
10596
|
+
if (current.length === 0)
|
|
10597
|
+
return next;
|
|
10598
|
+
if (next.length === 0 || current === next || current.includes(next))
|
|
10599
|
+
return current;
|
|
10600
|
+
if (next.includes(current))
|
|
10601
|
+
return next;
|
|
10602
|
+
return `${current}
|
|
10603
|
+
${next}`;
|
|
10604
|
+
}
|
|
10605
|
+
function backfillTranscriptsFromSummaryJobs(db) {
|
|
10606
|
+
if (!hasTable4(db, "summary_jobs"))
|
|
10607
|
+
return;
|
|
10608
|
+
const summaryColumns = tableColumns(db, "summary_jobs");
|
|
10609
|
+
if (!summaryColumns.has("transcript"))
|
|
10610
|
+
return;
|
|
10611
|
+
const select = (name) => summaryColumns.has(name) ? `"${name}" AS "${name}"` : `NULL AS "${name}"`;
|
|
10612
|
+
const jobs = db.prepare(`SELECT ${[
|
|
10613
|
+
"id",
|
|
10614
|
+
"session_key",
|
|
10615
|
+
"transcript",
|
|
10616
|
+
"harness",
|
|
10617
|
+
"project",
|
|
10618
|
+
"agent_id",
|
|
10619
|
+
"trigger",
|
|
10620
|
+
"boundary_reason",
|
|
10621
|
+
"captured_at",
|
|
10622
|
+
"ended_at",
|
|
10623
|
+
"completed_at",
|
|
10624
|
+
"created_at"
|
|
10625
|
+
].map(select).join(", ")} FROM summary_jobs`).all();
|
|
10626
|
+
const candidates = new Map;
|
|
10627
|
+
for (const job of jobs) {
|
|
10628
|
+
if (typeof job.transcript !== "string" || job.transcript.trim().length === 0)
|
|
10629
|
+
continue;
|
|
10630
|
+
const agentId = typeof job.agent_id === "string" && job.agent_id.length > 0 ? job.agent_id : "default";
|
|
10631
|
+
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}`)}`;
|
|
10632
|
+
const key = `${agentId}\x00${sessionKey}`;
|
|
10633
|
+
const current = candidates.get(key);
|
|
10634
|
+
const timestamp = summaryJobTimestamp(job);
|
|
10635
|
+
const boundary = isCompletionBoundary(job, summaryColumns);
|
|
10636
|
+
const createdAt = job.captured_at ?? job.created_at ?? job.ended_at ?? timestamp;
|
|
10637
|
+
if (!current) {
|
|
10638
|
+
candidates.set(key, {
|
|
10639
|
+
sessionKey,
|
|
10640
|
+
job: { ...job, agent_id: agentId },
|
|
10641
|
+
content: job.transcript,
|
|
10642
|
+
createdAt,
|
|
10643
|
+
completedAt: boundary ? timestamp : null
|
|
10644
|
+
});
|
|
10645
|
+
continue;
|
|
10646
|
+
}
|
|
10647
|
+
const currentTimestamp = summaryJobTimestamp(current.job);
|
|
10648
|
+
const preferred = timestamp > currentTimestamp || timestamp === currentTimestamp && job.transcript.length > current.content.length ? { ...job, agent_id: agentId } : current.job;
|
|
10649
|
+
candidates.set(key, {
|
|
10650
|
+
sessionKey,
|
|
10651
|
+
job: preferred,
|
|
10652
|
+
content: mergeTranscriptContent(current.content, job.transcript),
|
|
10653
|
+
createdAt: current.createdAt < createdAt ? current.createdAt : createdAt,
|
|
10654
|
+
completedAt: laterTimestamp(current.completedAt, boundary ? timestamp : null)
|
|
10655
|
+
});
|
|
10656
|
+
}
|
|
10657
|
+
const transcriptColumns = tableColumns(db, "session_transcripts");
|
|
10658
|
+
const hasUpdated = transcriptColumns.has("updated_at");
|
|
10659
|
+
const hasCompleted = transcriptColumns.has("completed_at");
|
|
10660
|
+
const hasHash = transcriptColumns.has("content_hash");
|
|
10661
|
+
const insertColumns = ["session_key", "content", "harness", "project", "agent_id", "created_at"];
|
|
10662
|
+
if (hasUpdated)
|
|
10663
|
+
insertColumns.push("updated_at");
|
|
10664
|
+
if (hasCompleted)
|
|
10665
|
+
insertColumns.push("completed_at");
|
|
10666
|
+
if (hasHash)
|
|
10667
|
+
insertColumns.push("content_hash");
|
|
10668
|
+
const insert = db.prepare(`INSERT OR IGNORE INTO session_transcripts (${insertColumns.join(", ")}) VALUES (${insertColumns.map(() => "?").join(", ")})`);
|
|
10669
|
+
const existing = db.prepare("SELECT content, completed_at FROM session_transcripts WHERE agent_id = ? AND session_key = ?");
|
|
10670
|
+
for (const candidate of candidates.values()) {
|
|
10671
|
+
const job = candidate.job;
|
|
10672
|
+
const agentId = job.agent_id ?? "default";
|
|
10673
|
+
const existingRow = existing.get(agentId, candidate.sessionKey);
|
|
10674
|
+
if (existingRow != null) {
|
|
10675
|
+
const previousContent = typeof existingRow.content === "string" ? existingRow.content : "";
|
|
10676
|
+
const mergedContent = mergeTranscriptContent(previousContent, candidate.content);
|
|
10677
|
+
const completedAt = typeof existingRow.completed_at === "string" && existingRow.completed_at.length > 0 ? existingRow.completed_at : candidate.completedAt;
|
|
10678
|
+
const assignments = ["content = ?"];
|
|
10679
|
+
const values2 = [mergedContent];
|
|
10680
|
+
if (hasUpdated && mergedContent !== previousContent) {
|
|
10681
|
+
assignments.push("updated_at = ?");
|
|
10682
|
+
values2.push(candidate.createdAt);
|
|
10683
|
+
}
|
|
10684
|
+
if (hasCompleted && completedAt && !existingRow.completed_at) {
|
|
10685
|
+
assignments.push("completed_at = ?");
|
|
10686
|
+
values2.push(completedAt);
|
|
10687
|
+
}
|
|
10688
|
+
if (hasHash) {
|
|
10689
|
+
assignments.push("content_hash = ?");
|
|
10690
|
+
values2.push(hashTranscript(mergedContent));
|
|
10691
|
+
}
|
|
10692
|
+
values2.push(agentId, candidate.sessionKey);
|
|
10693
|
+
db.prepare(`UPDATE session_transcripts SET ${assignments.join(", ")} WHERE agent_id = ? AND session_key = ?`).run(...values2);
|
|
10694
|
+
continue;
|
|
10695
|
+
}
|
|
10696
|
+
const values = [
|
|
10697
|
+
candidate.sessionKey,
|
|
10698
|
+
candidate.content,
|
|
10699
|
+
job.harness ?? null,
|
|
10700
|
+
job.project ?? null,
|
|
10701
|
+
agentId,
|
|
10702
|
+
candidate.createdAt
|
|
10703
|
+
];
|
|
10704
|
+
if (hasUpdated)
|
|
10705
|
+
values.push(candidate.createdAt);
|
|
10706
|
+
if (hasCompleted)
|
|
10707
|
+
values.push(candidate.completedAt);
|
|
10708
|
+
if (hasHash)
|
|
10709
|
+
values.push(hashTranscript(candidate.content));
|
|
10710
|
+
insert.run(...values);
|
|
10711
|
+
}
|
|
10712
|
+
}
|
|
10713
|
+
function up117(db) {
|
|
10714
|
+
if (!hasTable4(db, "session_transcripts"))
|
|
10715
|
+
return;
|
|
10716
|
+
addColumnIfMissing25(db, "session_transcripts", "completed_at", "TEXT");
|
|
10717
|
+
addColumnIfMissing25(db, "session_transcripts", "content_hash", "TEXT");
|
|
10718
|
+
backfillTranscriptHashes(db);
|
|
10719
|
+
if (hasTable4(db, "transcript_capture_jobs")) {
|
|
10720
|
+
const captureColumns = db.prepare("PRAGMA table_info(transcript_capture_jobs)").all();
|
|
10721
|
+
if (captureColumns.some((row) => row.name === "summary_status")) {
|
|
10722
|
+
db.exec("UPDATE transcript_capture_jobs SET summary_status = 'not_requested' WHERE summary_status IN ('pending', 'failed', 'skipped')");
|
|
10723
|
+
}
|
|
10724
|
+
}
|
|
10725
|
+
if (hasTable4(db, "summary_jobs")) {
|
|
10726
|
+
backfillTranscriptsFromSummaryJobs(db);
|
|
10727
|
+
backfillTranscriptHashes(db);
|
|
10728
|
+
const summaryColumns = tableColumns(db, "summary_jobs");
|
|
10729
|
+
const timestampParts = ["completed_at", "ended_at", "captured_at", "created_at"].filter((column) => summaryColumns.has(column)).map((column) => `sj.${column}`);
|
|
10730
|
+
const timestampValue = timestampParts.length === 1 ? timestampParts[0] : `COALESCE(${timestampParts.join(", ")})`;
|
|
10731
|
+
const completionTimestamp = timestampValue ? `MAX(${timestampValue})` : "NULL";
|
|
10732
|
+
const boundaryParts = [
|
|
10733
|
+
summaryColumns.has("trigger") ? "sj.trigger = 'session_end'" : null,
|
|
10734
|
+
summaryColumns.has("boundary_reason") ? "sj.boundary_reason IN ('session_closed', 'session_clear', 'stale_session', 'ttl_expired')" : null
|
|
10735
|
+
].filter((part) => part !== null);
|
|
10736
|
+
const boundaryPredicate = boundaryParts.length > 0 ? `(${boundaryParts.join(" OR ")})` : "1=1";
|
|
10737
|
+
const agentPredicate = summaryColumns.has("agent_id") ? "sj.agent_id = session_transcripts.agent_id" : "session_transcripts.agent_id = 'default'";
|
|
10738
|
+
if (completionTimestamp !== "NULL") {
|
|
10739
|
+
db.exec(`
|
|
10740
|
+
UPDATE session_transcripts
|
|
10741
|
+
SET completed_at = COALESCE(
|
|
10742
|
+
completed_at,
|
|
10743
|
+
(
|
|
10744
|
+
SELECT ${completionTimestamp}
|
|
10745
|
+
FROM summary_jobs AS sj
|
|
10746
|
+
WHERE ${agentPredicate}
|
|
10747
|
+
AND sj.session_key = session_transcripts.session_key
|
|
10748
|
+
AND ${boundaryPredicate}
|
|
10749
|
+
)
|
|
10750
|
+
)
|
|
10751
|
+
WHERE completed_at IS NULL;
|
|
10752
|
+
`);
|
|
10753
|
+
}
|
|
10754
|
+
db.exec("DELETE FROM summary_jobs");
|
|
10755
|
+
}
|
|
10756
|
+
const completionIndexColumns = ["agent_id", "completed_at"];
|
|
10757
|
+
if (tableColumns(db, "session_transcripts").has("updated_at"))
|
|
10758
|
+
completionIndexColumns.push("updated_at");
|
|
10759
|
+
db.exec(`
|
|
10760
|
+
CREATE INDEX IF NOT EXISTS idx_st_agent_completed
|
|
10761
|
+
ON session_transcripts(${completionIndexColumns.join(", ")});
|
|
10762
|
+
CREATE INDEX IF NOT EXISTS idx_st_agent_hash
|
|
10763
|
+
ON session_transcripts(agent_id, content_hash);
|
|
10764
|
+
`);
|
|
10765
|
+
}
|
|
10766
|
+
function up118(db) {
|
|
10767
|
+
db.exec(`
|
|
10768
|
+
CREATE INDEX IF NOT EXISTS idx_memory_jobs_pressure_status
|
|
10769
|
+
ON memory_jobs(status)
|
|
10770
|
+
WHERE status IN ('pending', 'leased') AND job_type <> 'extract';
|
|
10771
|
+
CREATE INDEX IF NOT EXISTS idx_memory_jobs_pressure_created_at
|
|
10772
|
+
ON memory_jobs(created_at)
|
|
10773
|
+
WHERE status IN ('pending', 'leased') AND job_type <> 'extract';
|
|
10774
|
+
CREATE INDEX IF NOT EXISTS idx_summary_jobs_pressure_status
|
|
10775
|
+
ON summary_jobs(status)
|
|
10776
|
+
WHERE status IN ('pending', 'leased');
|
|
10777
|
+
CREATE INDEX IF NOT EXISTS idx_summary_jobs_pressure_created_at
|
|
10778
|
+
ON summary_jobs(created_at)
|
|
10779
|
+
WHERE status IN ('pending', 'leased');
|
|
10780
|
+
`);
|
|
10781
|
+
}
|
|
10547
10782
|
var MIGRATIONS = [
|
|
10548
10783
|
{
|
|
10549
10784
|
version: 1,
|
|
@@ -11483,6 +11718,22 @@ var MIGRATIONS = [
|
|
|
11483
11718
|
{ table: "cross_agent_messages", column: "acp_target_agent_name" }
|
|
11484
11719
|
]
|
|
11485
11720
|
}
|
|
11721
|
+
},
|
|
11722
|
+
{
|
|
11723
|
+
version: 117,
|
|
11724
|
+
name: "retire-summary-worker",
|
|
11725
|
+
up: up117,
|
|
11726
|
+
artifacts: {
|
|
11727
|
+
columns: [
|
|
11728
|
+
{ table: "session_transcripts", column: "completed_at" },
|
|
11729
|
+
{ table: "session_transcripts", column: "content_hash" }
|
|
11730
|
+
]
|
|
11731
|
+
}
|
|
11732
|
+
},
|
|
11733
|
+
{
|
|
11734
|
+
version: 118,
|
|
11735
|
+
name: "queue-pressure-indices",
|
|
11736
|
+
up: up118
|
|
11486
11737
|
}
|
|
11487
11738
|
];
|
|
11488
11739
|
var LATEST_SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0;
|
|
@@ -11791,6 +12042,7 @@ function resolveSignetApiKey() {
|
|
|
11791
12042
|
import { createRequire as createRequire3 } from "node:module";
|
|
11792
12043
|
import { dirname as dirname2, join as join2 } from "node:path";
|
|
11793
12044
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
12045
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
11794
12046
|
import { homedir as homedir2 } from "os";
|
|
11795
12047
|
import { join as join22 } from "path";
|
|
11796
12048
|
import { createRequire as createRequire22 } from "node:module";
|
|
@@ -18750,7 +19002,7 @@ function memoriesFtsNeedsTokenizerRepair2(sql) {
|
|
|
18750
19002
|
return true;
|
|
18751
19003
|
return !normalized.includes(`tokenize='${MEMORIES_FTS_TOKENIZER2}'`);
|
|
18752
19004
|
}
|
|
18753
|
-
function
|
|
19005
|
+
function up119(db) {
|
|
18754
19006
|
db.exec(`
|
|
18755
19007
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
18756
19008
|
version INTEGER PRIMARY KEY,
|
|
@@ -18843,27 +19095,27 @@ function hasColumn22(db, table, column) {
|
|
|
18843
19095
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
18844
19096
|
return rows.some((r) => r.name === column);
|
|
18845
19097
|
}
|
|
18846
|
-
function
|
|
19098
|
+
function addColumnIfMissing26(db, table, column, definition) {
|
|
18847
19099
|
if (!hasColumn22(db, table, column)) {
|
|
18848
19100
|
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
18849
19101
|
}
|
|
18850
19102
|
}
|
|
18851
19103
|
function up210(db) {
|
|
18852
|
-
|
|
18853
|
-
|
|
18854
|
-
|
|
18855
|
-
|
|
18856
|
-
|
|
18857
|
-
|
|
18858
|
-
|
|
18859
|
-
|
|
18860
|
-
|
|
18861
|
-
|
|
18862
|
-
|
|
18863
|
-
|
|
18864
|
-
|
|
18865
|
-
|
|
18866
|
-
|
|
19104
|
+
addColumnIfMissing26(db, "memories", "content_hash", "TEXT");
|
|
19105
|
+
addColumnIfMissing26(db, "memories", "normalized_content", "TEXT");
|
|
19106
|
+
addColumnIfMissing26(db, "memories", "is_deleted", "INTEGER DEFAULT 0");
|
|
19107
|
+
addColumnIfMissing26(db, "memories", "deleted_at", "TEXT");
|
|
19108
|
+
addColumnIfMissing26(db, "memories", "extraction_status", "TEXT DEFAULT 'none'");
|
|
19109
|
+
addColumnIfMissing26(db, "memories", "embedding_model", "TEXT");
|
|
19110
|
+
addColumnIfMissing26(db, "memories", "extraction_model", "TEXT");
|
|
19111
|
+
addColumnIfMissing26(db, "memories", "update_count", "INTEGER DEFAULT 0");
|
|
19112
|
+
addColumnIfMissing26(db, "memories", "who", "TEXT");
|
|
19113
|
+
addColumnIfMissing26(db, "memories", "why", "TEXT");
|
|
19114
|
+
addColumnIfMissing26(db, "memories", "project", "TEXT");
|
|
19115
|
+
addColumnIfMissing26(db, "memories", "pinned", "INTEGER DEFAULT 0");
|
|
19116
|
+
addColumnIfMissing26(db, "memories", "importance", "REAL DEFAULT 0.5");
|
|
19117
|
+
addColumnIfMissing26(db, "memories", "last_accessed", "TEXT");
|
|
19118
|
+
addColumnIfMissing26(db, "memories", "access_count", "INTEGER DEFAULT 0");
|
|
18867
19119
|
db.exec(`
|
|
18868
19120
|
CREATE TABLE IF NOT EXISTS memory_history (
|
|
18869
19121
|
id TEXT PRIMARY KEY,
|
|
@@ -18959,7 +19211,7 @@ function up210(db) {
|
|
|
18959
19211
|
ON memory_entity_mentions(entity_id);
|
|
18960
19212
|
`);
|
|
18961
19213
|
}
|
|
18962
|
-
function
|
|
19214
|
+
function addColumnIfMissing27(db, table, column, definition) {
|
|
18963
19215
|
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
18964
19216
|
if (rows.some((r) => r.name === column))
|
|
18965
19217
|
return false;
|
|
@@ -18967,8 +19219,8 @@ function addColumnIfMissing26(db, table, column, definition) {
|
|
|
18967
19219
|
return true;
|
|
18968
19220
|
}
|
|
18969
19221
|
function up310(db) {
|
|
18970
|
-
|
|
18971
|
-
|
|
19222
|
+
addColumnIfMissing27(db, "memories", "why", "TEXT");
|
|
19223
|
+
addColumnIfMissing27(db, "memories", "project", "TEXT");
|
|
18972
19224
|
db.exec(`DROP INDEX IF EXISTS idx_memories_content_hash`);
|
|
18973
19225
|
db.exec(`
|
|
18974
19226
|
UPDATE memories
|
|
@@ -19173,7 +19425,7 @@ function up1010(db) {
|
|
|
19173
19425
|
)
|
|
19174
19426
|
`);
|
|
19175
19427
|
}
|
|
19176
|
-
function
|
|
19428
|
+
function up1110(db) {
|
|
19177
19429
|
db.exec(`
|
|
19178
19430
|
CREATE TABLE IF NOT EXISTS session_scores (
|
|
19179
19431
|
id TEXT PRIMARY KEY,
|
|
@@ -20394,7 +20646,7 @@ function up492(db) {
|
|
|
20394
20646
|
);
|
|
20395
20647
|
`);
|
|
20396
20648
|
}
|
|
20397
|
-
function
|
|
20649
|
+
function hasTable5(db, name) {
|
|
20398
20650
|
return db.prepare(`SELECT name
|
|
20399
20651
|
FROM sqlite_master
|
|
20400
20652
|
WHERE type = 'table' AND name = ?
|
|
@@ -20424,7 +20676,7 @@ function up502(db) {
|
|
|
20424
20676
|
CREATE INDEX IF NOT EXISTS idx_entity_dependency_history_created
|
|
20425
20677
|
ON entity_dependency_history(created_at DESC);
|
|
20426
20678
|
`);
|
|
20427
|
-
if (!
|
|
20679
|
+
if (!hasTable5(db, "entity_dependencies"))
|
|
20428
20680
|
return;
|
|
20429
20681
|
db.exec("DROP TRIGGER IF EXISTS trg_entity_dependencies_related_to_reason_insert");
|
|
20430
20682
|
db.exec("DROP TRIGGER IF EXISTS trg_entity_dependencies_related_to_reason_update");
|
|
@@ -22326,11 +22578,245 @@ function up1162(db) {
|
|
|
22326
22578
|
ON cross_agent_messages(delivery_path, delivery_state, delivery_lease_expires_at, delivery_updated_at);
|
|
22327
22579
|
`);
|
|
22328
22580
|
}
|
|
22581
|
+
function hasTable42(db, table) {
|
|
22582
|
+
return db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
|
|
22583
|
+
}
|
|
22584
|
+
function addColumnIfMissing252(db, table, column, definition) {
|
|
22585
|
+
const columns = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
22586
|
+
if (columns.some((row) => row.name === column))
|
|
22587
|
+
return;
|
|
22588
|
+
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
22589
|
+
}
|
|
22590
|
+
function tableColumns2(db, table) {
|
|
22591
|
+
const rows = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
22592
|
+
return new Set(rows.map((row) => typeof row.name === "string" ? row.name : ""));
|
|
22593
|
+
}
|
|
22594
|
+
function hashTranscript2(content) {
|
|
22595
|
+
return createHash2("sha256").update(content, "utf8").digest("hex");
|
|
22596
|
+
}
|
|
22597
|
+
function backfillTranscriptHashes2(db) {
|
|
22598
|
+
const columns = tableColumns2(db, "session_transcripts");
|
|
22599
|
+
if (!columns.has("content_hash") || !columns.has("content"))
|
|
22600
|
+
return;
|
|
22601
|
+
const rows = db.prepare("SELECT session_key, agent_id, content FROM session_transcripts WHERE content_hash IS NULL").all();
|
|
22602
|
+
const update = db.prepare("UPDATE session_transcripts SET content_hash = ? WHERE agent_id = ? AND session_key = ? AND content_hash IS NULL");
|
|
22603
|
+
for (const row of rows) {
|
|
22604
|
+
if (typeof row.content !== "string" || typeof row.session_key !== "string")
|
|
22605
|
+
continue;
|
|
22606
|
+
update.run(hashTranscript2(row.content), typeof row.agent_id === "string" ? row.agent_id : "default", row.session_key);
|
|
22607
|
+
}
|
|
22608
|
+
}
|
|
22609
|
+
var COMPLETION_BOUNDARY_REASONS2 = new Set(["session_closed", "session_clear", "stale_session", "ttl_expired"]);
|
|
22610
|
+
function summaryJobTimestamp2(job) {
|
|
22611
|
+
return job.completed_at ?? job.ended_at ?? job.captured_at ?? job.created_at ?? new Date(0).toISOString();
|
|
22612
|
+
}
|
|
22613
|
+
function laterTimestamp2(current, candidate) {
|
|
22614
|
+
if (current === null)
|
|
22615
|
+
return candidate;
|
|
22616
|
+
if (candidate === null)
|
|
22617
|
+
return current;
|
|
22618
|
+
const currentMillis = Date.parse(current);
|
|
22619
|
+
const candidateMillis = Date.parse(candidate);
|
|
22620
|
+
if (Number.isFinite(currentMillis) && Number.isFinite(candidateMillis)) {
|
|
22621
|
+
return candidateMillis > currentMillis ? candidate : current;
|
|
22622
|
+
}
|
|
22623
|
+
return candidate > current ? candidate : current;
|
|
22624
|
+
}
|
|
22625
|
+
function isCompletionBoundary2(job, columns) {
|
|
22626
|
+
return columns.has("trigger") && job.trigger === "session_end" || columns.has("boundary_reason") && COMPLETION_BOUNDARY_REASONS2.has(job.boundary_reason ?? "");
|
|
22627
|
+
}
|
|
22628
|
+
function mergeTranscriptContent2(current, next) {
|
|
22629
|
+
if (current.length === 0)
|
|
22630
|
+
return next;
|
|
22631
|
+
if (next.length === 0 || current === next || current.includes(next))
|
|
22632
|
+
return current;
|
|
22633
|
+
if (next.includes(current))
|
|
22634
|
+
return next;
|
|
22635
|
+
return `${current}
|
|
22636
|
+
${next}`;
|
|
22637
|
+
}
|
|
22638
|
+
function backfillTranscriptsFromSummaryJobs2(db) {
|
|
22639
|
+
if (!hasTable42(db, "summary_jobs"))
|
|
22640
|
+
return;
|
|
22641
|
+
const summaryColumns = tableColumns2(db, "summary_jobs");
|
|
22642
|
+
if (!summaryColumns.has("transcript"))
|
|
22643
|
+
return;
|
|
22644
|
+
const select = (name) => summaryColumns.has(name) ? `"${name}" AS "${name}"` : `NULL AS "${name}"`;
|
|
22645
|
+
const jobs = db.prepare(`SELECT ${[
|
|
22646
|
+
"id",
|
|
22647
|
+
"session_key",
|
|
22648
|
+
"transcript",
|
|
22649
|
+
"harness",
|
|
22650
|
+
"project",
|
|
22651
|
+
"agent_id",
|
|
22652
|
+
"trigger",
|
|
22653
|
+
"boundary_reason",
|
|
22654
|
+
"captured_at",
|
|
22655
|
+
"ended_at",
|
|
22656
|
+
"completed_at",
|
|
22657
|
+
"created_at"
|
|
22658
|
+
].map(select).join(", ")} FROM summary_jobs`).all();
|
|
22659
|
+
const candidates = new Map;
|
|
22660
|
+
for (const job of jobs) {
|
|
22661
|
+
if (typeof job.transcript !== "string" || job.transcript.trim().length === 0)
|
|
22662
|
+
continue;
|
|
22663
|
+
const agentId = typeof job.agent_id === "string" && job.agent_id.length > 0 ? job.agent_id : "default";
|
|
22664
|
+
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}`)}`;
|
|
22665
|
+
const key = `${agentId}\x00${sessionKey}`;
|
|
22666
|
+
const current = candidates.get(key);
|
|
22667
|
+
const timestamp = summaryJobTimestamp2(job);
|
|
22668
|
+
const boundary = isCompletionBoundary2(job, summaryColumns);
|
|
22669
|
+
const createdAt = job.captured_at ?? job.created_at ?? job.ended_at ?? timestamp;
|
|
22670
|
+
if (!current) {
|
|
22671
|
+
candidates.set(key, {
|
|
22672
|
+
sessionKey,
|
|
22673
|
+
job: { ...job, agent_id: agentId },
|
|
22674
|
+
content: job.transcript,
|
|
22675
|
+
createdAt,
|
|
22676
|
+
completedAt: boundary ? timestamp : null
|
|
22677
|
+
});
|
|
22678
|
+
continue;
|
|
22679
|
+
}
|
|
22680
|
+
const currentTimestamp = summaryJobTimestamp2(current.job);
|
|
22681
|
+
const preferred = timestamp > currentTimestamp || timestamp === currentTimestamp && job.transcript.length > current.content.length ? { ...job, agent_id: agentId } : current.job;
|
|
22682
|
+
candidates.set(key, {
|
|
22683
|
+
sessionKey,
|
|
22684
|
+
job: preferred,
|
|
22685
|
+
content: mergeTranscriptContent2(current.content, job.transcript),
|
|
22686
|
+
createdAt: current.createdAt < createdAt ? current.createdAt : createdAt,
|
|
22687
|
+
completedAt: laterTimestamp2(current.completedAt, boundary ? timestamp : null)
|
|
22688
|
+
});
|
|
22689
|
+
}
|
|
22690
|
+
const transcriptColumns = tableColumns2(db, "session_transcripts");
|
|
22691
|
+
const hasUpdated = transcriptColumns.has("updated_at");
|
|
22692
|
+
const hasCompleted = transcriptColumns.has("completed_at");
|
|
22693
|
+
const hasHash = transcriptColumns.has("content_hash");
|
|
22694
|
+
const insertColumns = ["session_key", "content", "harness", "project", "agent_id", "created_at"];
|
|
22695
|
+
if (hasUpdated)
|
|
22696
|
+
insertColumns.push("updated_at");
|
|
22697
|
+
if (hasCompleted)
|
|
22698
|
+
insertColumns.push("completed_at");
|
|
22699
|
+
if (hasHash)
|
|
22700
|
+
insertColumns.push("content_hash");
|
|
22701
|
+
const insert = db.prepare(`INSERT OR IGNORE INTO session_transcripts (${insertColumns.join(", ")}) VALUES (${insertColumns.map(() => "?").join(", ")})`);
|
|
22702
|
+
const existing = db.prepare("SELECT content, completed_at FROM session_transcripts WHERE agent_id = ? AND session_key = ?");
|
|
22703
|
+
for (const candidate of candidates.values()) {
|
|
22704
|
+
const job = candidate.job;
|
|
22705
|
+
const agentId = job.agent_id ?? "default";
|
|
22706
|
+
const existingRow = existing.get(agentId, candidate.sessionKey);
|
|
22707
|
+
if (existingRow != null) {
|
|
22708
|
+
const previousContent = typeof existingRow.content === "string" ? existingRow.content : "";
|
|
22709
|
+
const mergedContent = mergeTranscriptContent2(previousContent, candidate.content);
|
|
22710
|
+
const completedAt = typeof existingRow.completed_at === "string" && existingRow.completed_at.length > 0 ? existingRow.completed_at : candidate.completedAt;
|
|
22711
|
+
const assignments = ["content = ?"];
|
|
22712
|
+
const values2 = [mergedContent];
|
|
22713
|
+
if (hasUpdated && mergedContent !== previousContent) {
|
|
22714
|
+
assignments.push("updated_at = ?");
|
|
22715
|
+
values2.push(candidate.createdAt);
|
|
22716
|
+
}
|
|
22717
|
+
if (hasCompleted && completedAt && !existingRow.completed_at) {
|
|
22718
|
+
assignments.push("completed_at = ?");
|
|
22719
|
+
values2.push(completedAt);
|
|
22720
|
+
}
|
|
22721
|
+
if (hasHash) {
|
|
22722
|
+
assignments.push("content_hash = ?");
|
|
22723
|
+
values2.push(hashTranscript2(mergedContent));
|
|
22724
|
+
}
|
|
22725
|
+
values2.push(agentId, candidate.sessionKey);
|
|
22726
|
+
db.prepare(`UPDATE session_transcripts SET ${assignments.join(", ")} WHERE agent_id = ? AND session_key = ?`).run(...values2);
|
|
22727
|
+
continue;
|
|
22728
|
+
}
|
|
22729
|
+
const values = [
|
|
22730
|
+
candidate.sessionKey,
|
|
22731
|
+
candidate.content,
|
|
22732
|
+
job.harness ?? null,
|
|
22733
|
+
job.project ?? null,
|
|
22734
|
+
agentId,
|
|
22735
|
+
candidate.createdAt
|
|
22736
|
+
];
|
|
22737
|
+
if (hasUpdated)
|
|
22738
|
+
values.push(candidate.createdAt);
|
|
22739
|
+
if (hasCompleted)
|
|
22740
|
+
values.push(candidate.completedAt);
|
|
22741
|
+
if (hasHash)
|
|
22742
|
+
values.push(hashTranscript2(candidate.content));
|
|
22743
|
+
insert.run(...values);
|
|
22744
|
+
}
|
|
22745
|
+
}
|
|
22746
|
+
function up1172(db) {
|
|
22747
|
+
if (!hasTable42(db, "session_transcripts"))
|
|
22748
|
+
return;
|
|
22749
|
+
addColumnIfMissing252(db, "session_transcripts", "completed_at", "TEXT");
|
|
22750
|
+
addColumnIfMissing252(db, "session_transcripts", "content_hash", "TEXT");
|
|
22751
|
+
backfillTranscriptHashes2(db);
|
|
22752
|
+
if (hasTable42(db, "transcript_capture_jobs")) {
|
|
22753
|
+
const captureColumns = db.prepare("PRAGMA table_info(transcript_capture_jobs)").all();
|
|
22754
|
+
if (captureColumns.some((row) => row.name === "summary_status")) {
|
|
22755
|
+
db.exec("UPDATE transcript_capture_jobs SET summary_status = 'not_requested' WHERE summary_status IN ('pending', 'failed', 'skipped')");
|
|
22756
|
+
}
|
|
22757
|
+
}
|
|
22758
|
+
if (hasTable42(db, "summary_jobs")) {
|
|
22759
|
+
backfillTranscriptsFromSummaryJobs2(db);
|
|
22760
|
+
backfillTranscriptHashes2(db);
|
|
22761
|
+
const summaryColumns = tableColumns2(db, "summary_jobs");
|
|
22762
|
+
const timestampParts = ["completed_at", "ended_at", "captured_at", "created_at"].filter((column) => summaryColumns.has(column)).map((column) => `sj.${column}`);
|
|
22763
|
+
const timestampValue = timestampParts.length === 1 ? timestampParts[0] : `COALESCE(${timestampParts.join(", ")})`;
|
|
22764
|
+
const completionTimestamp = timestampValue ? `MAX(${timestampValue})` : "NULL";
|
|
22765
|
+
const boundaryParts = [
|
|
22766
|
+
summaryColumns.has("trigger") ? "sj.trigger = 'session_end'" : null,
|
|
22767
|
+
summaryColumns.has("boundary_reason") ? "sj.boundary_reason IN ('session_closed', 'session_clear', 'stale_session', 'ttl_expired')" : null
|
|
22768
|
+
].filter((part) => part !== null);
|
|
22769
|
+
const boundaryPredicate = boundaryParts.length > 0 ? `(${boundaryParts.join(" OR ")})` : "1=1";
|
|
22770
|
+
const agentPredicate = summaryColumns.has("agent_id") ? "sj.agent_id = session_transcripts.agent_id" : "session_transcripts.agent_id = 'default'";
|
|
22771
|
+
if (completionTimestamp !== "NULL") {
|
|
22772
|
+
db.exec(`
|
|
22773
|
+
UPDATE session_transcripts
|
|
22774
|
+
SET completed_at = COALESCE(
|
|
22775
|
+
completed_at,
|
|
22776
|
+
(
|
|
22777
|
+
SELECT ${completionTimestamp}
|
|
22778
|
+
FROM summary_jobs AS sj
|
|
22779
|
+
WHERE ${agentPredicate}
|
|
22780
|
+
AND sj.session_key = session_transcripts.session_key
|
|
22781
|
+
AND ${boundaryPredicate}
|
|
22782
|
+
)
|
|
22783
|
+
)
|
|
22784
|
+
WHERE completed_at IS NULL;
|
|
22785
|
+
`);
|
|
22786
|
+
}
|
|
22787
|
+
db.exec("DELETE FROM summary_jobs");
|
|
22788
|
+
}
|
|
22789
|
+
const completionIndexColumns = ["agent_id", "completed_at"];
|
|
22790
|
+
if (tableColumns2(db, "session_transcripts").has("updated_at"))
|
|
22791
|
+
completionIndexColumns.push("updated_at");
|
|
22792
|
+
db.exec(`
|
|
22793
|
+
CREATE INDEX IF NOT EXISTS idx_st_agent_completed
|
|
22794
|
+
ON session_transcripts(${completionIndexColumns.join(", ")});
|
|
22795
|
+
CREATE INDEX IF NOT EXISTS idx_st_agent_hash
|
|
22796
|
+
ON session_transcripts(agent_id, content_hash);
|
|
22797
|
+
`);
|
|
22798
|
+
}
|
|
22799
|
+
function up1182(db) {
|
|
22800
|
+
db.exec(`
|
|
22801
|
+
CREATE INDEX IF NOT EXISTS idx_memory_jobs_pressure_status
|
|
22802
|
+
ON memory_jobs(status)
|
|
22803
|
+
WHERE status IN ('pending', 'leased') AND job_type <> 'extract';
|
|
22804
|
+
CREATE INDEX IF NOT EXISTS idx_memory_jobs_pressure_created_at
|
|
22805
|
+
ON memory_jobs(created_at)
|
|
22806
|
+
WHERE status IN ('pending', 'leased') AND job_type <> 'extract';
|
|
22807
|
+
CREATE INDEX IF NOT EXISTS idx_summary_jobs_pressure_status
|
|
22808
|
+
ON summary_jobs(status)
|
|
22809
|
+
WHERE status IN ('pending', 'leased');
|
|
22810
|
+
CREATE INDEX IF NOT EXISTS idx_summary_jobs_pressure_created_at
|
|
22811
|
+
ON summary_jobs(created_at)
|
|
22812
|
+
WHERE status IN ('pending', 'leased');
|
|
22813
|
+
`);
|
|
22814
|
+
}
|
|
22329
22815
|
var MIGRATIONS2 = [
|
|
22330
22816
|
{
|
|
22331
22817
|
version: 1,
|
|
22332
22818
|
name: "baseline",
|
|
22333
|
-
up:
|
|
22819
|
+
up: up119,
|
|
22334
22820
|
artifacts: { tables: ["memories", "conversations", "embeddings"] }
|
|
22335
22821
|
},
|
|
22336
22822
|
{
|
|
@@ -22396,7 +22882,7 @@ var MIGRATIONS2 = [
|
|
|
22396
22882
|
{
|
|
22397
22883
|
version: 11,
|
|
22398
22884
|
name: "session-scores",
|
|
22399
|
-
up:
|
|
22885
|
+
up: up1110,
|
|
22400
22886
|
artifacts: { tables: ["session_scores"] }
|
|
22401
22887
|
},
|
|
22402
22888
|
{
|
|
@@ -23265,6 +23751,22 @@ var MIGRATIONS2 = [
|
|
|
23265
23751
|
{ table: "cross_agent_messages", column: "acp_target_agent_name" }
|
|
23266
23752
|
]
|
|
23267
23753
|
}
|
|
23754
|
+
},
|
|
23755
|
+
{
|
|
23756
|
+
version: 117,
|
|
23757
|
+
name: "retire-summary-worker",
|
|
23758
|
+
up: up1172,
|
|
23759
|
+
artifacts: {
|
|
23760
|
+
columns: [
|
|
23761
|
+
{ table: "session_transcripts", column: "completed_at" },
|
|
23762
|
+
{ table: "session_transcripts", column: "content_hash" }
|
|
23763
|
+
]
|
|
23764
|
+
}
|
|
23765
|
+
},
|
|
23766
|
+
{
|
|
23767
|
+
version: 118,
|
|
23768
|
+
name: "queue-pressure-indices",
|
|
23769
|
+
up: up1182
|
|
23268
23770
|
}
|
|
23269
23771
|
];
|
|
23270
23772
|
var LATEST_SCHEMA_VERSION2 = MIGRATIONS2[MIGRATIONS2.length - 1]?.version ?? 0;
|
|
@@ -23838,7 +24340,7 @@ function getConnectorVersion() {
|
|
|
23838
24340
|
}
|
|
23839
24341
|
function computePluginSourceHash() {
|
|
23840
24342
|
const sourceDir = getPluginSourceDir();
|
|
23841
|
-
const hash =
|
|
24343
|
+
const hash = createHash3("sha256");
|
|
23842
24344
|
for (const file of PLUGIN_FILES) {
|
|
23843
24345
|
const path = join4(sourceDir, file);
|
|
23844
24346
|
hash.update(file);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signetai/connector-hermes-agent",
|
|
3
|
-
"version": "0.185.
|
|
3
|
+
"version": "0.185.6",
|
|
4
4
|
"description": "Signet connector for Hermes Agent — installs Signet as a pluggable memory provider",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"typecheck": "tsc --noEmit"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@signetai/connector-base": "0.185.
|
|
29
|
-
"@signetai/core": "0.185.
|
|
28
|
+
"@signetai/connector-base": "0.185.6",
|
|
29
|
+
"@signetai/core": "0.185.6"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/node": "^22.0.0",
|