@signetai/connector-gemini 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.
Files changed (2) hide show
  1. package/dist/index.js +527 -25
  2. 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;
@@ -11938,6 +12189,7 @@ function resolveSignetWorkspacePath(home2 = homedir()) {
11938
12189
  import { createRequire as createRequire3 } from "node:module";
11939
12190
  import { dirname as dirname6, join as join4 } from "node:path";
11940
12191
  import { fileURLToPath as fileURLToPath2 } from "node:url";
12192
+ import { createHash as createHash2 } from "node:crypto";
11941
12193
  import { homedir as homedir22 } from "os";
11942
12194
  import { join as join22 } from "path";
11943
12195
  import { createRequire as createRequire22 } from "node:module";
@@ -18895,7 +19147,7 @@ function memoriesFtsNeedsTokenizerRepair2(sql) {
18895
19147
  return true;
18896
19148
  return !normalized.includes(`tokenize='${MEMORIES_FTS_TOKENIZER2}'`);
18897
19149
  }
18898
- function up117(db) {
19150
+ function up119(db) {
18899
19151
  db.exec(`
18900
19152
  CREATE TABLE IF NOT EXISTS schema_migrations (
18901
19153
  version INTEGER PRIMARY KEY,
@@ -18988,27 +19240,27 @@ function hasColumn22(db, table, column) {
18988
19240
  const rows = db.prepare(`PRAGMA table_info(${table})`).all();
18989
19241
  return rows.some((r) => r.name === column);
18990
19242
  }
18991
- function addColumnIfMissing25(db, table, column, definition) {
19243
+ function addColumnIfMissing26(db, table, column, definition) {
18992
19244
  if (!hasColumn22(db, table, column)) {
18993
19245
  db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
18994
19246
  }
18995
19247
  }
18996
19248
  function up210(db) {
18997
- addColumnIfMissing25(db, "memories", "content_hash", "TEXT");
18998
- addColumnIfMissing25(db, "memories", "normalized_content", "TEXT");
18999
- addColumnIfMissing25(db, "memories", "is_deleted", "INTEGER DEFAULT 0");
19000
- addColumnIfMissing25(db, "memories", "deleted_at", "TEXT");
19001
- addColumnIfMissing25(db, "memories", "extraction_status", "TEXT DEFAULT 'none'");
19002
- addColumnIfMissing25(db, "memories", "embedding_model", "TEXT");
19003
- addColumnIfMissing25(db, "memories", "extraction_model", "TEXT");
19004
- addColumnIfMissing25(db, "memories", "update_count", "INTEGER DEFAULT 0");
19005
- addColumnIfMissing25(db, "memories", "who", "TEXT");
19006
- addColumnIfMissing25(db, "memories", "why", "TEXT");
19007
- addColumnIfMissing25(db, "memories", "project", "TEXT");
19008
- addColumnIfMissing25(db, "memories", "pinned", "INTEGER DEFAULT 0");
19009
- addColumnIfMissing25(db, "memories", "importance", "REAL DEFAULT 0.5");
19010
- addColumnIfMissing25(db, "memories", "last_accessed", "TEXT");
19011
- addColumnIfMissing25(db, "memories", "access_count", "INTEGER DEFAULT 0");
19249
+ addColumnIfMissing26(db, "memories", "content_hash", "TEXT");
19250
+ addColumnIfMissing26(db, "memories", "normalized_content", "TEXT");
19251
+ addColumnIfMissing26(db, "memories", "is_deleted", "INTEGER DEFAULT 0");
19252
+ addColumnIfMissing26(db, "memories", "deleted_at", "TEXT");
19253
+ addColumnIfMissing26(db, "memories", "extraction_status", "TEXT DEFAULT 'none'");
19254
+ addColumnIfMissing26(db, "memories", "embedding_model", "TEXT");
19255
+ addColumnIfMissing26(db, "memories", "extraction_model", "TEXT");
19256
+ addColumnIfMissing26(db, "memories", "update_count", "INTEGER DEFAULT 0");
19257
+ addColumnIfMissing26(db, "memories", "who", "TEXT");
19258
+ addColumnIfMissing26(db, "memories", "why", "TEXT");
19259
+ addColumnIfMissing26(db, "memories", "project", "TEXT");
19260
+ addColumnIfMissing26(db, "memories", "pinned", "INTEGER DEFAULT 0");
19261
+ addColumnIfMissing26(db, "memories", "importance", "REAL DEFAULT 0.5");
19262
+ addColumnIfMissing26(db, "memories", "last_accessed", "TEXT");
19263
+ addColumnIfMissing26(db, "memories", "access_count", "INTEGER DEFAULT 0");
19012
19264
  db.exec(`
19013
19265
  CREATE TABLE IF NOT EXISTS memory_history (
19014
19266
  id TEXT PRIMARY KEY,
@@ -19104,7 +19356,7 @@ function up210(db) {
19104
19356
  ON memory_entity_mentions(entity_id);
19105
19357
  `);
19106
19358
  }
19107
- function addColumnIfMissing26(db, table, column, definition) {
19359
+ function addColumnIfMissing27(db, table, column, definition) {
19108
19360
  const rows = db.prepare(`PRAGMA table_info(${table})`).all();
19109
19361
  if (rows.some((r) => r.name === column))
19110
19362
  return false;
@@ -19112,8 +19364,8 @@ function addColumnIfMissing26(db, table, column, definition) {
19112
19364
  return true;
19113
19365
  }
19114
19366
  function up310(db) {
19115
- addColumnIfMissing26(db, "memories", "why", "TEXT");
19116
- addColumnIfMissing26(db, "memories", "project", "TEXT");
19367
+ addColumnIfMissing27(db, "memories", "why", "TEXT");
19368
+ addColumnIfMissing27(db, "memories", "project", "TEXT");
19117
19369
  db.exec(`DROP INDEX IF EXISTS idx_memories_content_hash`);
19118
19370
  db.exec(`
19119
19371
  UPDATE memories
@@ -19318,7 +19570,7 @@ function up1010(db) {
19318
19570
  )
19319
19571
  `);
19320
19572
  }
19321
- function up118(db) {
19573
+ function up1110(db) {
19322
19574
  db.exec(`
19323
19575
  CREATE TABLE IF NOT EXISTS session_scores (
19324
19576
  id TEXT PRIMARY KEY,
@@ -20539,7 +20791,7 @@ function up492(db) {
20539
20791
  );
20540
20792
  `);
20541
20793
  }
20542
- function hasTable4(db, name) {
20794
+ function hasTable5(db, name) {
20543
20795
  return db.prepare(`SELECT name
20544
20796
  FROM sqlite_master
20545
20797
  WHERE type = 'table' AND name = ?
@@ -20569,7 +20821,7 @@ function up502(db) {
20569
20821
  CREATE INDEX IF NOT EXISTS idx_entity_dependency_history_created
20570
20822
  ON entity_dependency_history(created_at DESC);
20571
20823
  `);
20572
- if (!hasTable4(db, "entity_dependencies"))
20824
+ if (!hasTable5(db, "entity_dependencies"))
20573
20825
  return;
20574
20826
  db.exec("DROP TRIGGER IF EXISTS trg_entity_dependencies_related_to_reason_insert");
20575
20827
  db.exec("DROP TRIGGER IF EXISTS trg_entity_dependencies_related_to_reason_update");
@@ -22471,11 +22723,245 @@ function up1162(db) {
22471
22723
  ON cross_agent_messages(delivery_path, delivery_state, delivery_lease_expires_at, delivery_updated_at);
22472
22724
  `);
22473
22725
  }
22726
+ function hasTable42(db, table) {
22727
+ return db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
22728
+ }
22729
+ function addColumnIfMissing252(db, table, column, definition) {
22730
+ const columns = db.prepare(`PRAGMA table_info(${table})`).all();
22731
+ if (columns.some((row) => row.name === column))
22732
+ return;
22733
+ db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
22734
+ }
22735
+ function tableColumns2(db, table) {
22736
+ const rows = db.prepare(`PRAGMA table_info(${table})`).all();
22737
+ return new Set(rows.map((row) => typeof row.name === "string" ? row.name : ""));
22738
+ }
22739
+ function hashTranscript2(content) {
22740
+ return createHash2("sha256").update(content, "utf8").digest("hex");
22741
+ }
22742
+ function backfillTranscriptHashes2(db) {
22743
+ const columns = tableColumns2(db, "session_transcripts");
22744
+ if (!columns.has("content_hash") || !columns.has("content"))
22745
+ return;
22746
+ const rows = db.prepare("SELECT session_key, agent_id, content FROM session_transcripts WHERE content_hash IS NULL").all();
22747
+ const update = db.prepare("UPDATE session_transcripts SET content_hash = ? WHERE agent_id = ? AND session_key = ? AND content_hash IS NULL");
22748
+ for (const row of rows) {
22749
+ if (typeof row.content !== "string" || typeof row.session_key !== "string")
22750
+ continue;
22751
+ update.run(hashTranscript2(row.content), typeof row.agent_id === "string" ? row.agent_id : "default", row.session_key);
22752
+ }
22753
+ }
22754
+ var COMPLETION_BOUNDARY_REASONS2 = new Set(["session_closed", "session_clear", "stale_session", "ttl_expired"]);
22755
+ function summaryJobTimestamp2(job) {
22756
+ return job.completed_at ?? job.ended_at ?? job.captured_at ?? job.created_at ?? new Date(0).toISOString();
22757
+ }
22758
+ function laterTimestamp2(current, candidate) {
22759
+ if (current === null)
22760
+ return candidate;
22761
+ if (candidate === null)
22762
+ return current;
22763
+ const currentMillis = Date.parse(current);
22764
+ const candidateMillis = Date.parse(candidate);
22765
+ if (Number.isFinite(currentMillis) && Number.isFinite(candidateMillis)) {
22766
+ return candidateMillis > currentMillis ? candidate : current;
22767
+ }
22768
+ return candidate > current ? candidate : current;
22769
+ }
22770
+ function isCompletionBoundary2(job, columns) {
22771
+ return columns.has("trigger") && job.trigger === "session_end" || columns.has("boundary_reason") && COMPLETION_BOUNDARY_REASONS2.has(job.boundary_reason ?? "");
22772
+ }
22773
+ function mergeTranscriptContent2(current, next) {
22774
+ if (current.length === 0)
22775
+ return next;
22776
+ if (next.length === 0 || current === next || current.includes(next))
22777
+ return current;
22778
+ if (next.includes(current))
22779
+ return next;
22780
+ return `${current}
22781
+ ${next}`;
22782
+ }
22783
+ function backfillTranscriptsFromSummaryJobs2(db) {
22784
+ if (!hasTable42(db, "summary_jobs"))
22785
+ return;
22786
+ const summaryColumns = tableColumns2(db, "summary_jobs");
22787
+ if (!summaryColumns.has("transcript"))
22788
+ return;
22789
+ const select = (name) => summaryColumns.has(name) ? `"${name}" AS "${name}"` : `NULL AS "${name}"`;
22790
+ const jobs = db.prepare(`SELECT ${[
22791
+ "id",
22792
+ "session_key",
22793
+ "transcript",
22794
+ "harness",
22795
+ "project",
22796
+ "agent_id",
22797
+ "trigger",
22798
+ "boundary_reason",
22799
+ "captured_at",
22800
+ "ended_at",
22801
+ "completed_at",
22802
+ "created_at"
22803
+ ].map(select).join(", ")} FROM summary_jobs`).all();
22804
+ const candidates = new Map;
22805
+ for (const job of jobs) {
22806
+ if (typeof job.transcript !== "string" || job.transcript.trim().length === 0)
22807
+ continue;
22808
+ const agentId = typeof job.agent_id === "string" && job.agent_id.length > 0 ? job.agent_id : "default";
22809
+ 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}`)}`;
22810
+ const key = `${agentId}\x00${sessionKey}`;
22811
+ const current = candidates.get(key);
22812
+ const timestamp = summaryJobTimestamp2(job);
22813
+ const boundary = isCompletionBoundary2(job, summaryColumns);
22814
+ const createdAt = job.captured_at ?? job.created_at ?? job.ended_at ?? timestamp;
22815
+ if (!current) {
22816
+ candidates.set(key, {
22817
+ sessionKey,
22818
+ job: { ...job, agent_id: agentId },
22819
+ content: job.transcript,
22820
+ createdAt,
22821
+ completedAt: boundary ? timestamp : null
22822
+ });
22823
+ continue;
22824
+ }
22825
+ const currentTimestamp = summaryJobTimestamp2(current.job);
22826
+ const preferred = timestamp > currentTimestamp || timestamp === currentTimestamp && job.transcript.length > current.content.length ? { ...job, agent_id: agentId } : current.job;
22827
+ candidates.set(key, {
22828
+ sessionKey,
22829
+ job: preferred,
22830
+ content: mergeTranscriptContent2(current.content, job.transcript),
22831
+ createdAt: current.createdAt < createdAt ? current.createdAt : createdAt,
22832
+ completedAt: laterTimestamp2(current.completedAt, boundary ? timestamp : null)
22833
+ });
22834
+ }
22835
+ const transcriptColumns = tableColumns2(db, "session_transcripts");
22836
+ const hasUpdated = transcriptColumns.has("updated_at");
22837
+ const hasCompleted = transcriptColumns.has("completed_at");
22838
+ const hasHash = transcriptColumns.has("content_hash");
22839
+ const insertColumns = ["session_key", "content", "harness", "project", "agent_id", "created_at"];
22840
+ if (hasUpdated)
22841
+ insertColumns.push("updated_at");
22842
+ if (hasCompleted)
22843
+ insertColumns.push("completed_at");
22844
+ if (hasHash)
22845
+ insertColumns.push("content_hash");
22846
+ const insert = db.prepare(`INSERT OR IGNORE INTO session_transcripts (${insertColumns.join(", ")}) VALUES (${insertColumns.map(() => "?").join(", ")})`);
22847
+ const existing = db.prepare("SELECT content, completed_at FROM session_transcripts WHERE agent_id = ? AND session_key = ?");
22848
+ for (const candidate of candidates.values()) {
22849
+ const job = candidate.job;
22850
+ const agentId = job.agent_id ?? "default";
22851
+ const existingRow = existing.get(agentId, candidate.sessionKey);
22852
+ if (existingRow != null) {
22853
+ const previousContent = typeof existingRow.content === "string" ? existingRow.content : "";
22854
+ const mergedContent = mergeTranscriptContent2(previousContent, candidate.content);
22855
+ const completedAt = typeof existingRow.completed_at === "string" && existingRow.completed_at.length > 0 ? existingRow.completed_at : candidate.completedAt;
22856
+ const assignments = ["content = ?"];
22857
+ const values2 = [mergedContent];
22858
+ if (hasUpdated && mergedContent !== previousContent) {
22859
+ assignments.push("updated_at = ?");
22860
+ values2.push(candidate.createdAt);
22861
+ }
22862
+ if (hasCompleted && completedAt && !existingRow.completed_at) {
22863
+ assignments.push("completed_at = ?");
22864
+ values2.push(completedAt);
22865
+ }
22866
+ if (hasHash) {
22867
+ assignments.push("content_hash = ?");
22868
+ values2.push(hashTranscript2(mergedContent));
22869
+ }
22870
+ values2.push(agentId, candidate.sessionKey);
22871
+ db.prepare(`UPDATE session_transcripts SET ${assignments.join(", ")} WHERE agent_id = ? AND session_key = ?`).run(...values2);
22872
+ continue;
22873
+ }
22874
+ const values = [
22875
+ candidate.sessionKey,
22876
+ candidate.content,
22877
+ job.harness ?? null,
22878
+ job.project ?? null,
22879
+ agentId,
22880
+ candidate.createdAt
22881
+ ];
22882
+ if (hasUpdated)
22883
+ values.push(candidate.createdAt);
22884
+ if (hasCompleted)
22885
+ values.push(candidate.completedAt);
22886
+ if (hasHash)
22887
+ values.push(hashTranscript2(candidate.content));
22888
+ insert.run(...values);
22889
+ }
22890
+ }
22891
+ function up1172(db) {
22892
+ if (!hasTable42(db, "session_transcripts"))
22893
+ return;
22894
+ addColumnIfMissing252(db, "session_transcripts", "completed_at", "TEXT");
22895
+ addColumnIfMissing252(db, "session_transcripts", "content_hash", "TEXT");
22896
+ backfillTranscriptHashes2(db);
22897
+ if (hasTable42(db, "transcript_capture_jobs")) {
22898
+ const captureColumns = db.prepare("PRAGMA table_info(transcript_capture_jobs)").all();
22899
+ if (captureColumns.some((row) => row.name === "summary_status")) {
22900
+ db.exec("UPDATE transcript_capture_jobs SET summary_status = 'not_requested' WHERE summary_status IN ('pending', 'failed', 'skipped')");
22901
+ }
22902
+ }
22903
+ if (hasTable42(db, "summary_jobs")) {
22904
+ backfillTranscriptsFromSummaryJobs2(db);
22905
+ backfillTranscriptHashes2(db);
22906
+ const summaryColumns = tableColumns2(db, "summary_jobs");
22907
+ const timestampParts = ["completed_at", "ended_at", "captured_at", "created_at"].filter((column) => summaryColumns.has(column)).map((column) => `sj.${column}`);
22908
+ const timestampValue = timestampParts.length === 1 ? timestampParts[0] : `COALESCE(${timestampParts.join(", ")})`;
22909
+ const completionTimestamp = timestampValue ? `MAX(${timestampValue})` : "NULL";
22910
+ const boundaryParts = [
22911
+ summaryColumns.has("trigger") ? "sj.trigger = 'session_end'" : null,
22912
+ summaryColumns.has("boundary_reason") ? "sj.boundary_reason IN ('session_closed', 'session_clear', 'stale_session', 'ttl_expired')" : null
22913
+ ].filter((part) => part !== null);
22914
+ const boundaryPredicate = boundaryParts.length > 0 ? `(${boundaryParts.join(" OR ")})` : "1=1";
22915
+ const agentPredicate = summaryColumns.has("agent_id") ? "sj.agent_id = session_transcripts.agent_id" : "session_transcripts.agent_id = 'default'";
22916
+ if (completionTimestamp !== "NULL") {
22917
+ db.exec(`
22918
+ UPDATE session_transcripts
22919
+ SET completed_at = COALESCE(
22920
+ completed_at,
22921
+ (
22922
+ SELECT ${completionTimestamp}
22923
+ FROM summary_jobs AS sj
22924
+ WHERE ${agentPredicate}
22925
+ AND sj.session_key = session_transcripts.session_key
22926
+ AND ${boundaryPredicate}
22927
+ )
22928
+ )
22929
+ WHERE completed_at IS NULL;
22930
+ `);
22931
+ }
22932
+ db.exec("DELETE FROM summary_jobs");
22933
+ }
22934
+ const completionIndexColumns = ["agent_id", "completed_at"];
22935
+ if (tableColumns2(db, "session_transcripts").has("updated_at"))
22936
+ completionIndexColumns.push("updated_at");
22937
+ db.exec(`
22938
+ CREATE INDEX IF NOT EXISTS idx_st_agent_completed
22939
+ ON session_transcripts(${completionIndexColumns.join(", ")});
22940
+ CREATE INDEX IF NOT EXISTS idx_st_agent_hash
22941
+ ON session_transcripts(agent_id, content_hash);
22942
+ `);
22943
+ }
22944
+ function up1182(db) {
22945
+ db.exec(`
22946
+ CREATE INDEX IF NOT EXISTS idx_memory_jobs_pressure_status
22947
+ ON memory_jobs(status)
22948
+ WHERE status IN ('pending', 'leased') AND job_type <> 'extract';
22949
+ CREATE INDEX IF NOT EXISTS idx_memory_jobs_pressure_created_at
22950
+ ON memory_jobs(created_at)
22951
+ WHERE status IN ('pending', 'leased') AND job_type <> 'extract';
22952
+ CREATE INDEX IF NOT EXISTS idx_summary_jobs_pressure_status
22953
+ ON summary_jobs(status)
22954
+ WHERE status IN ('pending', 'leased');
22955
+ CREATE INDEX IF NOT EXISTS idx_summary_jobs_pressure_created_at
22956
+ ON summary_jobs(created_at)
22957
+ WHERE status IN ('pending', 'leased');
22958
+ `);
22959
+ }
22474
22960
  var MIGRATIONS2 = [
22475
22961
  {
22476
22962
  version: 1,
22477
22963
  name: "baseline",
22478
- up: up117,
22964
+ up: up119,
22479
22965
  artifacts: { tables: ["memories", "conversations", "embeddings"] }
22480
22966
  },
22481
22967
  {
@@ -22541,7 +23027,7 @@ var MIGRATIONS2 = [
22541
23027
  {
22542
23028
  version: 11,
22543
23029
  name: "session-scores",
22544
- up: up118,
23030
+ up: up1110,
22545
23031
  artifacts: { tables: ["session_scores"] }
22546
23032
  },
22547
23033
  {
@@ -23410,6 +23896,22 @@ var MIGRATIONS2 = [
23410
23896
  { table: "cross_agent_messages", column: "acp_target_agent_name" }
23411
23897
  ]
23412
23898
  }
23899
+ },
23900
+ {
23901
+ version: 117,
23902
+ name: "retire-summary-worker",
23903
+ up: up1172,
23904
+ artifacts: {
23905
+ columns: [
23906
+ { table: "session_transcripts", column: "completed_at" },
23907
+ { table: "session_transcripts", column: "content_hash" }
23908
+ ]
23909
+ }
23910
+ },
23911
+ {
23912
+ version: 118,
23913
+ name: "queue-pressure-indices",
23914
+ up: up1182
23413
23915
  }
23414
23916
  ];
23415
23917
  var LATEST_SCHEMA_VERSION2 = MIGRATIONS2[MIGRATIONS2.length - 1]?.version ?? 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signetai/connector-gemini",
3
- "version": "0.185.4",
3
+ "version": "0.185.6",
4
4
  "description": "Signet connector for Gemini CLI",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -24,8 +24,8 @@
24
24
  "typecheck": "tsc --noEmit"
25
25
  },
26
26
  "dependencies": {
27
- "@signetai/connector-base": "0.185.4",
28
- "@signetai/core": "0.185.4"
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",