signetai 0.185.3 → 0.185.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mcp-stdio.js CHANGED
@@ -36498,6 +36498,14 @@ var EPISODIC_CAPTURED_AT_FLOOR = "2000-01-01T00:00:00.000Z";
36498
36498
  function readNonEmptyTrimmed(value) {
36499
36499
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
36500
36500
  }
36501
+ function tableHasColumn(db, table, column) {
36502
+ try {
36503
+ const rows = db.prepare(`PRAGMA table_info(${table})`).all();
36504
+ return rows.some((row) => row.name === column);
36505
+ } catch {
36506
+ return false;
36507
+ }
36508
+ }
36501
36509
  function sourceIdCandidates(value) {
36502
36510
  const trimmed = value.trim();
36503
36511
  const stripped = trimmed.replace(/^(memory|artifact|source|transcript|session|summary):/, "");
@@ -36580,15 +36588,18 @@ function readEpisodicArtifact(db, agentId, id) {
36580
36588
  function readEpisodicTranscript(db, agentId, id) {
36581
36589
  const ids = sourceIdCandidates(id);
36582
36590
  const placeholders = ids.map(() => "?").join(", ");
36583
- const row = db.prepare(`SELECT st.session_key, st.content, st.harness, st.project, st.created_at, st.updated_at,
36584
- EXISTS (
36585
- SELECT 1 FROM summary_jobs AS sj
36586
- WHERE sj.agent_id = st.agent_id AND sj.session_key = st.session_key
36587
- AND sj.trigger IN ('session_end', 'ttl_expired')
36588
- ) AS completed
36591
+ const hasUpdated = tableHasColumn(db, "session_transcripts", "updated_at");
36592
+ const hasCompleted = tableHasColumn(db, "session_transcripts", "completed_at");
36593
+ const updatedAt = hasUpdated ? "st.updated_at" : "NULL";
36594
+ const completedAt = hasCompleted ? "st.completed_at" : "NULL";
36595
+ const capturedAt = `COALESCE(${completedAt}, ${updatedAt}, st.created_at)`;
36596
+ const orderBy = `${capturedAt} DESC, st.created_at DESC`;
36597
+ const completed = hasCompleted ? "st.completed_at IS NOT NULL" : "0";
36598
+ const row = db.prepare(`SELECT st.session_key, st.content, st.harness, st.project, st.created_at, ${updatedAt} AS updated_at,
36599
+ ${completedAt} AS completed_at, ${completed} AS completed
36589
36600
  FROM session_transcripts AS st
36590
36601
  WHERE st.agent_id = ? AND st.session_key IN (${placeholders})
36591
- ORDER BY st.updated_at DESC, st.created_at DESC
36602
+ ORDER BY ${orderBy}
36592
36603
  LIMIT 1`).get(agentId, ...ids);
36593
36604
  if (!row)
36594
36605
  return null;
@@ -36602,7 +36613,7 @@ function readEpisodicTranscript(db, agentId, id) {
36602
36613
  sourcePath: null,
36603
36614
  project: row.project,
36604
36615
  harness: row.harness,
36605
- capturedAt: row.updated_at ?? row.created_at,
36616
+ capturedAt: row.completed_at ?? row.updated_at ?? row.created_at,
36606
36617
  evidenceMeta: null,
36607
36618
  completed: row.completed === 1
36608
36619
  };
@@ -36702,6 +36713,8 @@ function searchEpisodicSources(db, params) {
36702
36713
  const like = `%${query}%`;
36703
36714
  const sinceArgs = params.since !== undefined ? [params.since, EPISODIC_CAPTURED_AT_FLOOR] : [];
36704
36715
  const beforeArgs = params.before !== undefined ? [params.before] : [];
36716
+ const transcriptSearchTime = tableHasColumn(db, "session_transcripts", "updated_at") ? "COALESCE(updated_at, created_at)" : "created_at";
36717
+ const transcriptCompleted = tableHasColumn(db, "session_transcripts", "completed_at") ? "completed_at IS NOT NULL" : "0";
36705
36718
  const branches = [];
36706
36719
  if (params.kind === undefined || params.kind === "memory") {
36707
36720
  branches.push({
@@ -36736,15 +36749,15 @@ function searchEpisodicSources(db, params) {
36736
36749
  }
36737
36750
  if (params.kind === undefined || params.kind === "transcript") {
36738
36751
  branches.push({
36739
- sql: `SELECT 'transcript' AS kind, session_key AS id, COALESCE(updated_at, created_at) AS captured_at
36752
+ sql: `SELECT 'transcript' AS kind, session_key AS id, ${transcriptSearchTime} AS captured_at
36740
36753
  FROM session_transcripts
36741
- WHERE agent_id = ? AND content LIKE ?
36742
- ${params.since ? "AND (julianday(COALESCE(updated_at, created_at)) >= julianday(?) OR julianday(COALESCE(updated_at, created_at)) < julianday(?))" : ""}
36743
- ${params.before ? "AND julianday(COALESCE(updated_at, created_at)) <= julianday(?)" : ""}`,
36754
+ WHERE agent_id = ? AND ${transcriptCompleted} AND content LIKE ?
36755
+ ${params.since ? `AND (julianday(${transcriptSearchTime}) >= julianday(?) OR julianday(${transcriptSearchTime}) < julianday(?))` : ""}
36756
+ ${params.before ? `AND julianday(${transcriptSearchTime}) <= julianday(?)` : ""}`,
36744
36757
  args: [params.agentId, like, ...sinceArgs, ...beforeArgs]
36745
36758
  });
36746
36759
  }
36747
- if (params.kind === undefined || params.kind === "summary") {
36760
+ if (params.kind === "summary") {
36748
36761
  branches.push({
36749
36762
  sql: `SELECT 'summary' AS kind, id, latest_at AS captured_at
36750
36763
  FROM session_summaries
@@ -36772,6 +36785,7 @@ UNION ALL
36772
36785
  import { createRequire as createRequire2 } from "node:module";
36773
36786
  import { dirname, join } from "node:path";
36774
36787
  import { fileURLToPath } from "node:url";
36788
+ import { createHash } from "node:crypto";
36775
36789
  import { homedir as homedir2 } from "os";
36776
36790
  import { join as join2 } from "path";
36777
36791
  import { createRequire as createRequire22 } from "node:module";
@@ -43875,7 +43889,9 @@ function buildRecallRequestBody(query, options = {}) {
43875
43889
  sourceOnly: options.sourceOnly === true || options.source_only === true ? true : undefined,
43876
43890
  aggregate: options.aggregate === true ? true : undefined,
43877
43891
  aggregateBudget: options.aggregateBudget ?? options.aggregate_budget,
43878
- saveAggregate: options.saveAggregate === false || options.save_aggregate === false ? false : options.saveAggregate === true || options.save_aggregate === true ? true : undefined
43892
+ saveAggregate: options.saveAggregate === false || options.save_aggregate === false ? false : options.saveAggregate === true || options.save_aggregate === true ? true : undefined,
43893
+ minScore: typeof options.minScore === "number" && Number.isFinite(options.minScore) ? options.minScore : undefined,
43894
+ recallSurface: options.recallSurface
43879
43895
  });
43880
43896
  }
43881
43897
  function normalizeStructuredMemoryPayload(value) {
@@ -47568,6 +47584,224 @@ function up116(db) {
47568
47584
  ON cross_agent_messages(delivery_path, delivery_state, delivery_lease_expires_at, delivery_updated_at);
47569
47585
  `);
47570
47586
  }
47587
+ function hasTable4(db, table) {
47588
+ return db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
47589
+ }
47590
+ function addColumnIfMissing25(db, table, column, definition) {
47591
+ const columns = db.prepare(`PRAGMA table_info(${table})`).all();
47592
+ if (columns.some((row) => row.name === column))
47593
+ return;
47594
+ db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
47595
+ }
47596
+ function tableColumns(db, table) {
47597
+ const rows = db.prepare(`PRAGMA table_info(${table})`).all();
47598
+ return new Set(rows.map((row) => typeof row.name === "string" ? row.name : ""));
47599
+ }
47600
+ function hashTranscript(content) {
47601
+ return createHash("sha256").update(content, "utf8").digest("hex");
47602
+ }
47603
+ function backfillTranscriptHashes(db) {
47604
+ const columns = tableColumns(db, "session_transcripts");
47605
+ if (!columns.has("content_hash") || !columns.has("content"))
47606
+ return;
47607
+ const rows = db.prepare("SELECT session_key, agent_id, content FROM session_transcripts WHERE content_hash IS NULL").all();
47608
+ const update = db.prepare("UPDATE session_transcripts SET content_hash = ? WHERE agent_id = ? AND session_key = ? AND content_hash IS NULL");
47609
+ for (const row of rows) {
47610
+ if (typeof row.content !== "string" || typeof row.session_key !== "string")
47611
+ continue;
47612
+ update.run(hashTranscript(row.content), typeof row.agent_id === "string" ? row.agent_id : "default", row.session_key);
47613
+ }
47614
+ }
47615
+ var COMPLETION_BOUNDARY_REASONS = new Set(["session_closed", "session_clear", "stale_session", "ttl_expired"]);
47616
+ function summaryJobTimestamp(job) {
47617
+ return job.completed_at ?? job.ended_at ?? job.captured_at ?? job.created_at ?? new Date(0).toISOString();
47618
+ }
47619
+ function laterTimestamp(current, candidate) {
47620
+ if (current === null)
47621
+ return candidate;
47622
+ if (candidate === null)
47623
+ return current;
47624
+ const currentMillis = Date.parse(current);
47625
+ const candidateMillis = Date.parse(candidate);
47626
+ if (Number.isFinite(currentMillis) && Number.isFinite(candidateMillis)) {
47627
+ return candidateMillis > currentMillis ? candidate : current;
47628
+ }
47629
+ return candidate > current ? candidate : current;
47630
+ }
47631
+ function isCompletionBoundary(job, columns) {
47632
+ return columns.has("trigger") && job.trigger === "session_end" || columns.has("boundary_reason") && COMPLETION_BOUNDARY_REASONS.has(job.boundary_reason ?? "");
47633
+ }
47634
+ function mergeTranscriptContent(current, next) {
47635
+ if (current.length === 0)
47636
+ return next;
47637
+ if (next.length === 0 || current === next || current.includes(next))
47638
+ return current;
47639
+ if (next.includes(current))
47640
+ return next;
47641
+ return `${current}
47642
+ ${next}`;
47643
+ }
47644
+ function backfillTranscriptsFromSummaryJobs(db) {
47645
+ if (!hasTable4(db, "summary_jobs"))
47646
+ return;
47647
+ const summaryColumns = tableColumns(db, "summary_jobs");
47648
+ if (!summaryColumns.has("transcript"))
47649
+ return;
47650
+ const select = (name) => summaryColumns.has(name) ? `"${name}" AS "${name}"` : `NULL AS "${name}"`;
47651
+ const jobs = db.prepare(`SELECT ${[
47652
+ "id",
47653
+ "session_key",
47654
+ "transcript",
47655
+ "harness",
47656
+ "project",
47657
+ "agent_id",
47658
+ "trigger",
47659
+ "boundary_reason",
47660
+ "captured_at",
47661
+ "ended_at",
47662
+ "completed_at",
47663
+ "created_at"
47664
+ ].map(select).join(", ")} FROM summary_jobs`).all();
47665
+ const candidates = new Map;
47666
+ for (const job of jobs) {
47667
+ if (typeof job.transcript !== "string" || job.transcript.trim().length === 0)
47668
+ continue;
47669
+ const agentId = typeof job.agent_id === "string" && job.agent_id.length > 0 ? job.agent_id : "default";
47670
+ 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}`)}`;
47671
+ const key = `${agentId}\x00${sessionKey}`;
47672
+ const current = candidates.get(key);
47673
+ const timestamp = summaryJobTimestamp(job);
47674
+ const boundary = isCompletionBoundary(job, summaryColumns);
47675
+ const createdAt = job.captured_at ?? job.created_at ?? job.ended_at ?? timestamp;
47676
+ if (!current) {
47677
+ candidates.set(key, {
47678
+ sessionKey,
47679
+ job: { ...job, agent_id: agentId },
47680
+ content: job.transcript,
47681
+ createdAt,
47682
+ completedAt: boundary ? timestamp : null
47683
+ });
47684
+ continue;
47685
+ }
47686
+ const currentTimestamp = summaryJobTimestamp(current.job);
47687
+ const preferred = timestamp > currentTimestamp || timestamp === currentTimestamp && job.transcript.length > current.content.length ? { ...job, agent_id: agentId } : current.job;
47688
+ candidates.set(key, {
47689
+ sessionKey,
47690
+ job: preferred,
47691
+ content: mergeTranscriptContent(current.content, job.transcript),
47692
+ createdAt: current.createdAt < createdAt ? current.createdAt : createdAt,
47693
+ completedAt: laterTimestamp(current.completedAt, boundary ? timestamp : null)
47694
+ });
47695
+ }
47696
+ const transcriptColumns = tableColumns(db, "session_transcripts");
47697
+ const hasUpdated = transcriptColumns.has("updated_at");
47698
+ const hasCompleted = transcriptColumns.has("completed_at");
47699
+ const hasHash = transcriptColumns.has("content_hash");
47700
+ const insertColumns = ["session_key", "content", "harness", "project", "agent_id", "created_at"];
47701
+ if (hasUpdated)
47702
+ insertColumns.push("updated_at");
47703
+ if (hasCompleted)
47704
+ insertColumns.push("completed_at");
47705
+ if (hasHash)
47706
+ insertColumns.push("content_hash");
47707
+ const insert = db.prepare(`INSERT OR IGNORE INTO session_transcripts (${insertColumns.join(", ")}) VALUES (${insertColumns.map(() => "?").join(", ")})`);
47708
+ const existing = db.prepare("SELECT content, completed_at FROM session_transcripts WHERE agent_id = ? AND session_key = ?");
47709
+ for (const candidate of candidates.values()) {
47710
+ const job = candidate.job;
47711
+ const agentId = job.agent_id ?? "default";
47712
+ const existingRow = existing.get(agentId, candidate.sessionKey);
47713
+ if (existingRow != null) {
47714
+ const previousContent = typeof existingRow.content === "string" ? existingRow.content : "";
47715
+ const mergedContent = mergeTranscriptContent(previousContent, candidate.content);
47716
+ const completedAt = typeof existingRow.completed_at === "string" && existingRow.completed_at.length > 0 ? existingRow.completed_at : candidate.completedAt;
47717
+ const assignments = ["content = ?"];
47718
+ const values2 = [mergedContent];
47719
+ if (hasUpdated && mergedContent !== previousContent) {
47720
+ assignments.push("updated_at = ?");
47721
+ values2.push(candidate.createdAt);
47722
+ }
47723
+ if (hasCompleted && completedAt && !existingRow.completed_at) {
47724
+ assignments.push("completed_at = ?");
47725
+ values2.push(completedAt);
47726
+ }
47727
+ if (hasHash) {
47728
+ assignments.push("content_hash = ?");
47729
+ values2.push(hashTranscript(mergedContent));
47730
+ }
47731
+ values2.push(agentId, candidate.sessionKey);
47732
+ db.prepare(`UPDATE session_transcripts SET ${assignments.join(", ")} WHERE agent_id = ? AND session_key = ?`).run(...values2);
47733
+ continue;
47734
+ }
47735
+ const values = [
47736
+ candidate.sessionKey,
47737
+ candidate.content,
47738
+ job.harness ?? null,
47739
+ job.project ?? null,
47740
+ agentId,
47741
+ candidate.createdAt
47742
+ ];
47743
+ if (hasUpdated)
47744
+ values.push(candidate.createdAt);
47745
+ if (hasCompleted)
47746
+ values.push(candidate.completedAt);
47747
+ if (hasHash)
47748
+ values.push(hashTranscript(candidate.content));
47749
+ insert.run(...values);
47750
+ }
47751
+ }
47752
+ function up117(db) {
47753
+ if (!hasTable4(db, "session_transcripts"))
47754
+ return;
47755
+ addColumnIfMissing25(db, "session_transcripts", "completed_at", "TEXT");
47756
+ addColumnIfMissing25(db, "session_transcripts", "content_hash", "TEXT");
47757
+ backfillTranscriptHashes(db);
47758
+ if (hasTable4(db, "transcript_capture_jobs")) {
47759
+ const captureColumns = db.prepare("PRAGMA table_info(transcript_capture_jobs)").all();
47760
+ if (captureColumns.some((row) => row.name === "summary_status")) {
47761
+ db.exec("UPDATE transcript_capture_jobs SET summary_status = 'not_requested' WHERE summary_status IN ('pending', 'failed', 'skipped')");
47762
+ }
47763
+ }
47764
+ if (hasTable4(db, "summary_jobs")) {
47765
+ backfillTranscriptsFromSummaryJobs(db);
47766
+ backfillTranscriptHashes(db);
47767
+ const summaryColumns = tableColumns(db, "summary_jobs");
47768
+ const timestampParts = ["completed_at", "ended_at", "captured_at", "created_at"].filter((column) => summaryColumns.has(column)).map((column) => `sj.${column}`);
47769
+ const timestampValue = timestampParts.length === 1 ? timestampParts[0] : `COALESCE(${timestampParts.join(", ")})`;
47770
+ const completionTimestamp = timestampValue ? `MAX(${timestampValue})` : "NULL";
47771
+ const boundaryParts = [
47772
+ summaryColumns.has("trigger") ? "sj.trigger = 'session_end'" : null,
47773
+ summaryColumns.has("boundary_reason") ? "sj.boundary_reason IN ('session_closed', 'session_clear', 'stale_session', 'ttl_expired')" : null
47774
+ ].filter((part) => part !== null);
47775
+ const boundaryPredicate = boundaryParts.length > 0 ? `(${boundaryParts.join(" OR ")})` : "1=1";
47776
+ const agentPredicate = summaryColumns.has("agent_id") ? "sj.agent_id = session_transcripts.agent_id" : "session_transcripts.agent_id = 'default'";
47777
+ if (completionTimestamp !== "NULL") {
47778
+ db.exec(`
47779
+ UPDATE session_transcripts
47780
+ SET completed_at = COALESCE(
47781
+ completed_at,
47782
+ (
47783
+ SELECT ${completionTimestamp}
47784
+ FROM summary_jobs AS sj
47785
+ WHERE ${agentPredicate}
47786
+ AND sj.session_key = session_transcripts.session_key
47787
+ AND ${boundaryPredicate}
47788
+ )
47789
+ )
47790
+ WHERE completed_at IS NULL;
47791
+ `);
47792
+ }
47793
+ db.exec("DELETE FROM summary_jobs");
47794
+ }
47795
+ const completionIndexColumns = ["agent_id", "completed_at"];
47796
+ if (tableColumns(db, "session_transcripts").has("updated_at"))
47797
+ completionIndexColumns.push("updated_at");
47798
+ db.exec(`
47799
+ CREATE INDEX IF NOT EXISTS idx_st_agent_completed
47800
+ ON session_transcripts(${completionIndexColumns.join(", ")});
47801
+ CREATE INDEX IF NOT EXISTS idx_st_agent_hash
47802
+ ON session_transcripts(agent_id, content_hash);
47803
+ `);
47804
+ }
47571
47805
  var MIGRATIONS = [
47572
47806
  {
47573
47807
  version: 1,
@@ -48507,6 +48741,17 @@ var MIGRATIONS = [
48507
48741
  { table: "cross_agent_messages", column: "acp_target_agent_name" }
48508
48742
  ]
48509
48743
  }
48744
+ },
48745
+ {
48746
+ version: 117,
48747
+ name: "retire-summary-worker",
48748
+ up: up117,
48749
+ artifacts: {
48750
+ columns: [
48751
+ { table: "session_transcripts", column: "completed_at" },
48752
+ { table: "session_transcripts", column: "content_hash" }
48753
+ ]
48754
+ }
48510
48755
  }
48511
48756
  ];
48512
48757
  var LATEST_SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0;
@@ -49456,12 +49701,18 @@ function nextDreamingEvidenceFragment(source, start, maxChars) {
49456
49701
  for (let index = cappedEnd - 1;index > start; index -= 1) {
49457
49702
  const character = content[index];
49458
49703
  const previous = content[index - 1];
49704
+ if (character === undefined || previous === undefined)
49705
+ continue;
49459
49706
  if (character === `
49460
49707
  ` && previous === `
49461
49708
  ` || /\s/.test(character) && /[.!?]/.test(previous)) {
49462
49709
  let boundaryEnd = index + 1;
49463
- while (boundaryEnd < content.length && /\s/.test(content[boundaryEnd]))
49710
+ while (boundaryEnd < content.length) {
49711
+ const next = content[boundaryEnd];
49712
+ if (next === undefined || !/\s/.test(next))
49713
+ break;
49464
49714
  boundaryEnd += 1;
49715
+ }
49465
49716
  if (boundaryEnd <= cappedEnd && content.slice(start, boundaryEnd).trim().length > 0) {
49466
49717
  end = boundaryEnd;
49467
49718
  break;
@@ -49518,10 +49769,189 @@ function renderDreamingEvidenceMeta(evidenceMeta) {
49518
49769
  ${lines.join(`
49519
49770
  `)}` : "";
49520
49771
  }
49772
+ function objectValue(value, key) {
49773
+ return value[key];
49774
+ }
49775
+ function stringValue(value) {
49776
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
49777
+ }
49778
+ function toolName(value) {
49779
+ const functionValue = value.function;
49780
+ if (typeof functionValue === "object" && functionValue !== null && !Array.isArray(functionValue)) {
49781
+ const name = stringValue(functionValue.name);
49782
+ if (name)
49783
+ return name;
49784
+ }
49785
+ for (const key of ["name", "tool", "tool_name", "toolName", "recipient_name"]) {
49786
+ const name = stringValue(objectValue(value, key));
49787
+ if (name)
49788
+ return name;
49789
+ }
49790
+ const item = value.item;
49791
+ if (typeof item === "object" && item !== null && !Array.isArray(item))
49792
+ return toolName(item);
49793
+ const payload = value.payload;
49794
+ if (typeof payload === "object" && payload !== null && !Array.isArray(payload)) {
49795
+ const name = toolName(payload);
49796
+ if (name !== "tool")
49797
+ return name;
49798
+ }
49799
+ return "tool";
49800
+ }
49801
+ function toolMarker(value) {
49802
+ return `[tool call: ${toolName(value)}]`;
49803
+ }
49804
+ function contentText(value) {
49805
+ if (typeof value === "string")
49806
+ return value.trim().length > 0 ? [value.trim()] : [];
49807
+ if (!Array.isArray(value))
49808
+ return [];
49809
+ const text = [];
49810
+ for (const item of value) {
49811
+ if (typeof item === "string") {
49812
+ if (item.trim().length > 0)
49813
+ text.push(item.trim());
49814
+ continue;
49815
+ }
49816
+ if (typeof item !== "object" || item === null || Array.isArray(item))
49817
+ continue;
49818
+ const block = item;
49819
+ const type = stringValue(block.type)?.toLowerCase() ?? "";
49820
+ if (["tool_result", "tool_response", "function_call_output", "function_result"].includes(type))
49821
+ continue;
49822
+ if (["tool_use", "tool_call", "function_call"].includes(type)) {
49823
+ text.push(toolMarker(block));
49824
+ continue;
49825
+ }
49826
+ const blockText = stringValue(block.text) ?? stringValue(block.content);
49827
+ if (blockText)
49828
+ text.push(blockText);
49829
+ }
49830
+ return text;
49831
+ }
49832
+ function jsonTranscriptLine(value) {
49833
+ if (typeof value !== "object" || value === null || Array.isArray(value))
49834
+ return [];
49835
+ const record5 = value;
49836
+ const nestedItem = record5.item;
49837
+ const item = typeof nestedItem === "object" && nestedItem !== null && !Array.isArray(nestedItem) ? nestedItem : record5;
49838
+ const type = (stringValue(item.type) ?? stringValue(record5.type) ?? "").toLowerCase();
49839
+ if (["tool_result", "tool_response", "function_call_output", "function_result", "tool_output", "tool_return"].some((candidate) => type.includes(candidate))) {
49840
+ return [];
49841
+ }
49842
+ if (["tool_use", "tool_call", "function_call", "function_calling"].some((candidate) => type.includes(candidate))) {
49843
+ return [toolMarker(item)];
49844
+ }
49845
+ const role = (stringValue(item.role) ?? stringValue(record5.role) ?? "").toLowerCase();
49846
+ if (role === "tool" || role === "function")
49847
+ return [];
49848
+ const payload = record5.payload;
49849
+ if (typeof payload === "object" && payload !== null && !Array.isArray(payload)) {
49850
+ const payloadRecord = payload;
49851
+ const payloadType = (stringValue(payloadRecord.type) ?? "").toLowerCase();
49852
+ if (payloadType.includes("tool") || payloadType.includes("function_call")) {
49853
+ if (payloadType.includes("result") || payloadType.includes("output"))
49854
+ return [];
49855
+ return [toolMarker(payloadRecord)];
49856
+ }
49857
+ const payloadRole = stringValue(payloadRecord.role)?.toLowerCase();
49858
+ const payloadText = contentText(payloadRecord.content ?? payloadRecord.text);
49859
+ if (payloadRole && payloadText.length > 0)
49860
+ return [`${payloadRole === "user" ? "User" : "Assistant"}: ${payloadText.join(`
49861
+ `)}`];
49862
+ }
49863
+ const text = contentText(item.content ?? item.text ?? item.message);
49864
+ if (text.length === 0)
49865
+ return [];
49866
+ const label = role === "user" ? "User" : role === "assistant" ? "Assistant" : role === "reasoning" ? "Assistant reasoning" : null;
49867
+ return label ? text.map((part) => `${label}: ${part}`) : text;
49868
+ }
49869
+ function sanitizePlainTranscript(content) {
49870
+ const withoutToolBlocks = content.replace(/<(?:tool_result|tool_output|function_result|function_output|tool_response)>[\s\S]*?<\/(?:tool_result|tool_output|function_result|function_output|tool_response)>/gi, "").replace(/<(?:tool_call|tool_use|function_call)(?:\s+([^>]*))?>[\s\S]*?<\/(?:tool_call|tool_use|function_call)>/gi, (_match, attributes) => {
49871
+ const name = /(?:name|tool)=["']([^"']+)["']/i.exec(attributes ?? "")?.[1] ?? "tool";
49872
+ return `[tool call: ${name}]`;
49873
+ });
49874
+ const lines = withoutToolBlocks.split(/\r?\n/);
49875
+ const kept = [];
49876
+ for (const line of lines) {
49877
+ const trimmed = line.trim();
49878
+ if (/^(?:tool[_ -]?(?:output|result)|function[_ -]?(?:output|result)|<tool_result|<tool_response)\b/i.test(trimmed))
49879
+ continue;
49880
+ if (/^(?:tool[_ -]?(?:call|use)|function[_ -]?call)\b/i.test(trimmed)) {
49881
+ const name = trimmed.split(/\s*[:=]\s*/, 2)[1]?.trim() || "tool";
49882
+ kept.push(`[tool call: ${name.replace(/[\s\[({].*$/, "")}]`);
49883
+ continue;
49884
+ }
49885
+ kept.push(line);
49886
+ }
49887
+ return kept.join(`
49888
+ `).replace(/\n{3,}/g, `
49889
+
49890
+ `).trim();
49891
+ }
49892
+ function isJsonTranscriptToolOutput(value) {
49893
+ if (typeof value !== "object" || value === null || Array.isArray(value))
49894
+ return false;
49895
+ const record5 = value;
49896
+ const nestedItem = record5.item;
49897
+ const item = typeof nestedItem === "object" && nestedItem !== null && !Array.isArray(nestedItem) ? nestedItem : record5;
49898
+ const type = (stringValue(item.type) ?? stringValue(record5.type) ?? "").toLowerCase();
49899
+ if (["tool_result", "tool_response", "function_call_output", "function_result", "tool_output", "tool_return"].some((candidate) => type.includes(candidate)))
49900
+ return true;
49901
+ const role = (stringValue(item.role) ?? stringValue(record5.role) ?? "").toLowerCase();
49902
+ if (role === "tool" || role === "function")
49903
+ return true;
49904
+ const payload = record5.payload;
49905
+ if (typeof payload === "object" && payload !== null && !Array.isArray(payload)) {
49906
+ const payloadRecord = payload;
49907
+ const payloadType = (stringValue(payloadRecord.type) ?? "").toLowerCase();
49908
+ const payloadRole = (stringValue(payloadRecord.role) ?? "").toLowerCase();
49909
+ return payloadType.includes("result") || payloadType.includes("output") || payloadRole === "tool" || payloadRole === "function";
49910
+ }
49911
+ return false;
49912
+ }
49913
+ function sanitizeTranscriptForDreaming(content) {
49914
+ const lines = content.split(/\r?\n/);
49915
+ const nonEmptyLines = lines.filter((line) => line.trim().length > 0);
49916
+ const jsonLines = [];
49917
+ let parsedLines = 0;
49918
+ let recognizedJsonLines = 0;
49919
+ for (const line of nonEmptyLines) {
49920
+ try {
49921
+ const parsed = JSON.parse(line.trim());
49922
+ parsedLines += 1;
49923
+ const rendered = jsonTranscriptLine(parsed);
49924
+ if (rendered.length > 0) {
49925
+ recognizedJsonLines += 1;
49926
+ jsonLines.push(...rendered);
49927
+ }
49928
+ } catch {}
49929
+ }
49930
+ if (parsedLines === nonEmptyLines.length && recognizedJsonLines > 0)
49931
+ return jsonLines.join(`
49932
+ `).trim();
49933
+ const mixedLines = lines.flatMap((line) => {
49934
+ const trimmed = line.trim();
49935
+ if (trimmed.length === 0)
49936
+ return [line];
49937
+ try {
49938
+ const parsed = JSON.parse(trimmed);
49939
+ const rendered = jsonTranscriptLine(parsed);
49940
+ if (rendered.length > 0)
49941
+ return rendered;
49942
+ if (isJsonTranscriptToolOutput(parsed))
49943
+ return [];
49944
+ } catch {}
49945
+ return [line];
49946
+ });
49947
+ return sanitizePlainTranscript(mixedLines.join(`
49948
+ `));
49949
+ }
49521
49950
  function renderDreamingEvidence(source) {
49951
+ const content = source.kind === "transcript" || source.sourceKind === "transcript" ? sanitizeTranscriptForDreaming(source.content) : source.content;
49522
49952
  const metadata = renderDreamingEvidenceMeta(source.evidenceMeta);
49523
- return metadata ? `${source.content}
49524
- ${metadata}` : source.content;
49953
+ return metadata ? `${content}
49954
+ ${metadata}` : content;
49525
49955
  }
49526
49956
  function createDreamingAgentEvidence(evidence) {
49527
49957
  return evidence.map((item) => {
@@ -52938,8 +53368,9 @@ function citeEvidence(accessor, agentId, citation) {
52938
53368
  return { evidence: null, sourceAgentIds: [] };
52939
53369
  const result = accessor.withReadDb((db) => {
52940
53370
  const source = readEpisodicSource(db, { agentId, from: requested.sourceRef });
52941
- if (source !== null)
53371
+ if (source !== null && (source.kind !== "transcript" || source.completed)) {
52942
53372
  return { evidence: createDreamingAgentEvidence([source]), sourceAgentIds: [] };
53373
+ }
52943
53374
  return { evidence: [], sourceAgentIds: findEpisodicSourceAgentIds(db, requested.sourceRef) };
52944
53375
  });
52945
53376
  return {
@@ -53822,7 +54253,7 @@ function createDreamingCapabilities(params) {
53822
54253
  }
53823
54254
  return { ok: true, result: getOntologyLinkEvidence(accessor, { agentId: scopeId, id: ref3.id }) };
53824
54255
  }),
53825
- capability("search_evidence", "Search episodic evidence", "Full-text search immutable episodic memories, artifacts, transcripts, and summaries in one agent scope. Results contain exact bounded excerpts of the rendered evidence with contentOffset/contentLength; use sourceRef for citations, which are validated against the complete canonical source. Each record carries completed: memory, artifact, and summary records are settled captures (true); a transcript is true once a session-end summary job has been triggered for its session (the session ended), whether or not the summary itself landed, and false while the session is still running — do not file claims from a still-growing transcript, since its states may be contradicted by the session's end. If contentTruncated is true, page exact fragments with the same sourceRef and chunkSize: start at offset=0 when contentHasPrevious is true, then use offset=contentOffset+content.length from the fragment just returned until contentHasNext is false. Omit the query AND since to list the unprocessed window: the listing starts at the scope's evidence watermark (the last pass's surfaced frontier), so the newest unseen sources come first. Narrow with a query if the list is large; pass an explicit earlier since only when you need older history. Artifacts are deduped by content hash: content-identical files across vault paths collapse to one canonical entry.", true, exports_external.object({
54256
+ capability("search_evidence", "Search episodic evidence", "Full-text search immutable episodic memories, artifacts, and transcripts in one agent scope. Historical summary records can be requested explicitly with kind=summary, but are not part of the default Dreaming delivery path. Results contain exact bounded excerpts of the rendered evidence with contentOffset/contentLength; use sourceRef for citations, which are validated against the complete canonical source. Each record carries completed: memory, artifact, and summary records are settled captures (true); a transcript is true only after the session-end machinery writes its completion marker, and false while the session is still running — do not file claims from a still-growing transcript, since its states may be contradicted by the session's end. If contentTruncated is true, page exact fragments with the same sourceRef and chunkSize: start at offset=0 when contentHasPrevious is true, then use offset=contentOffset+content.length from the fragment just returned until contentHasNext is false. Omit the query AND since to list the unprocessed window: the listing starts at the scope's evidence watermark (the last pass's surfaced frontier), so the newest unseen sources come first. Narrow with a query if the list is large; pass an explicit earlier since only when you need older history. Artifacts are deduped by content hash: content-identical files across vault paths collapse to one canonical entry.", true, exports_external.object({
53826
54257
  agentId: exports_external.string().min(1),
53827
54258
  query: exports_external.string().optional(),
53828
54259
  since: exports_external.string().optional(),
@@ -53837,6 +54268,9 @@ function createDreamingCapabilities(params) {
53837
54268
  const source = readEpisodicSource(db, { agentId: scopeId, from: sourceRef });
53838
54269
  if (source === null)
53839
54270
  return { ok: false, error: "Evidence source not found" };
54271
+ if (source.kind === "transcript" && !source.completed) {
54272
+ return { ok: false, error: "Transcript is still in progress" };
54273
+ }
53840
54274
  const fragment = projectEvidenceFragment(source, Math.max(0, Math.floor(offset ?? 0)), Math.min(Math.max(Math.floor(chunkSize ?? MAX_EVIDENCE_EXCERPT_CHARS), 1), MAX_EVIDENCE_EXCERPT_CHARS));
53841
54275
  return fragment === null ? { ok: false, error: "Evidence fragment offset is outside the source" } : { ok: true, items: [fragment] };
53842
54276
  }
@@ -55445,8 +55879,8 @@ function errorResult(msg) {
55445
55879
  isError: true
55446
55880
  };
55447
55881
  }
55448
- async function graphIqToolResult(args, label, toolName, pluginHostProvider) {
55449
- const access = graphIqToolAccess(toolName, pluginHostProvider());
55882
+ async function graphIqToolResult(args, label, toolName2, pluginHostProvider) {
55883
+ const access = graphIqToolAccess(toolName2, pluginHostProvider());
55450
55884
  if (!access.ok)
55451
55885
  return errorResult(access.error);
55452
55886
  try {
@@ -55467,8 +55901,8 @@ ${stderr}`);
55467
55901
  return errorResult(`${label}: ${message}`);
55468
55902
  }
55469
55903
  }
55470
- function graphIqToolAccess(toolName, pluginHost) {
55471
- const resolved = GRAPHIQ_COMPAT_ALIASES.get(toolName) ?? toolName;
55904
+ function graphIqToolAccess(toolName2, pluginHost) {
55905
+ const resolved = GRAPHIQ_COMPAT_ALIASES.get(toolName2) ?? toolName2;
55472
55906
  const plugin = pluginHost.get(SIGNET_GRAPHIQ_PLUGIN_ID);
55473
55907
  const pluginActive = plugin?.state === "active" || plugin?.state === "degraded";
55474
55908
  if (!pluginActive) {
@@ -55494,8 +55928,8 @@ function sanitizeToolSegment(value) {
55494
55928
  const normalized = value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
55495
55929
  return normalized.length > 0 ? normalized : "tool";
55496
55930
  }
55497
- function buildProxyToolName(used, serverId, toolName) {
55498
- const base = `signet_${sanitizeToolSegment(serverId)}_${sanitizeToolSegment(toolName)}`;
55931
+ function buildProxyToolName(used, serverId, toolName2) {
55932
+ const base = `signet_${sanitizeToolSegment(serverId)}_${sanitizeToolSegment(toolName2)}`;
55499
55933
  if (!used.has(base)) {
55500
55934
  used.add(base);
55501
55935
  return base;
@@ -55864,7 +56298,7 @@ async function createMcpServer(opts) {
55864
56298
  pinned: exports_external.boolean().optional().describe("Only return pinned memories"),
55865
56299
  importance_min: exports_external.number().optional().describe("Minimum memory importance threshold"),
55866
56300
  min_score: exports_external.number().optional().describe("Deprecated compatibility alias for importance_min; ignored when importance_min is also set"),
55867
- score_min: exports_external.number().optional().describe("Minimum recall score threshold (client-side)"),
56301
+ score_min: exports_external.number().optional().describe("Minimum recall score threshold; applied by the daemon and checked defensively by the adapter"),
55868
56302
  aggregate: exports_external.boolean().optional().describe("Synthesize an aggregate answer from bounded recall evidence"),
55869
56303
  aggregate_budget: exports_external.enum(["small", "medium", "large"]).optional().describe("Aggregate recall budget"),
55870
56304
  save_aggregate: exports_external.boolean().optional().describe("Save the aggregate answer as a memory"),
@@ -55916,7 +56350,9 @@ async function createMcpServer(opts) {
55916
56350
  sessionKey: session_key,
55917
56351
  agentId: agent_id,
55918
56352
  includeRecalled: include_recalled,
55919
- scope
56353
+ scope,
56354
+ minScore: score_min,
56355
+ recallSurface: "tool_call"
55920
56356
  })
55921
56357
  });
55922
56358
  if (!result.ok) {
@@ -55943,7 +56379,7 @@ async function createMcpServer(opts) {
55943
56379
  mode: exports_external.enum(["auto", "timeline", "filter"]).optional()
55944
56380
  }).optional().describe("Temporal recall range/facet options for date and timeline queries"),
55945
56381
  keyword_query: exports_external.string().optional().describe("Override the keyword/FTS query used for recall"),
55946
- score_min: exports_external.number().optional().describe("Minimum recall score threshold (client-side)"),
56382
+ score_min: exports_external.number().optional().describe("Minimum recall score threshold; applied by the daemon and checked defensively by the adapter"),
55947
56383
  aggregate: exports_external.boolean().optional().describe("Synthesize an aggregate answer from bounded recall evidence"),
55948
56384
  aggregate_budget: exports_external.enum(["small", "medium", "large"]).optional().describe("Aggregate recall budget"),
55949
56385
  save_aggregate: exports_external.boolean().optional().describe("Save the aggregate answer as a memory"),
@@ -55990,7 +56426,9 @@ async function createMcpServer(opts) {
55990
56426
  sessionKey: session_key,
55991
56427
  agentId: agent_id,
55992
56428
  includeRecalled: include_recalled,
55993
- scope
56429
+ scope,
56430
+ minScore: score_min,
56431
+ recallSurface: "tool_call"
55994
56432
  })
55995
56433
  });
55996
56434
  if (!result.ok)
@@ -56017,7 +56455,8 @@ async function createMcpServer(opts) {
56017
56455
  project,
56018
56456
  sessionKey: session_key,
56019
56457
  agentId: agent_id,
56020
- includeRecalled: include_recalled
56458
+ includeRecalled: include_recalled,
56459
+ recallSurface: "tool_call"
56021
56460
  }),
56022
56461
  sourceOnly: true
56023
56462
  }
@@ -1,43 +1,43 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "0.185.3",
3
+ "version": "0.185.5",
4
4
  "assets": [
5
5
  {
6
6
  "name": "signet-darwin-arm64",
7
7
  "platform": "darwin-arm64",
8
- "sha256": "a87e4df39dfe910277f4fcefed625011551765074c829ba036a36e0146fb1f87",
9
- "size": 117424672
8
+ "sha256": "a21bfe6c9e7bb50e58907a2f97562b91c2aeb80455e0f4b550d656a624b58c8c",
9
+ "size": 117606304
10
10
  },
11
11
  {
12
12
  "name": "signet-darwin-x64",
13
13
  "platform": "darwin-x64",
14
- "sha256": "9dbcd64e3cb9cb883a4935a2368c126449171c5c50c47eb919593bb20b298844",
15
- "size": 122047040
14
+ "sha256": "d44f1c9f5000ddb26b0fc04e473937087e712f5c46b65dad3005cb7a889a9ebe",
15
+ "size": 122227264
16
16
  },
17
17
  {
18
18
  "name": "signet-linux-arm64",
19
19
  "platform": "linux-arm64",
20
- "sha256": "61db96d6a3d122ec580d29506be4f4f90c1342e19cef76542973d4a3f7a17f33",
21
- "size": 154653776
20
+ "sha256": "9e10952521ef512aea40db2de54adb6d3e4b8b6993dd8a1d0a416222786ed6cd",
21
+ "size": 154845735
22
22
  },
23
23
  {
24
24
  "name": "signet-linux-x64",
25
25
  "platform": "linux-x64",
26
- "sha256": "f7feaf0ba73f790dc7afcc8efb0507e4fb5dbc3b4ead168ec016861b4e175486",
27
- "size": 155212761
26
+ "sha256": "ac3d8e682a51bd6a16f91023bfbfa6d9cf3340113bbf6731179ec1a845a8588b",
27
+ "size": 155404720
28
28
  },
29
29
  {
30
30
  "name": "signet-win32-x64.exe",
31
31
  "platform": "win32-x64",
32
- "sha256": "c8292568089e356bb58995c111117ebdf25eb17454e132f8c79cd4fbe67fe8b6",
33
- "size": 171345920
32
+ "sha256": "bbd21424c33bf6101215b94794c95b5adbbcb810cbcd6f5787b456c470534274",
33
+ "size": 171537920
34
34
  }
35
35
  ],
36
36
  "components": {
37
37
  "connectors": {
38
- "url": "signet-connectors-0.185.3.tar.gz",
39
- "sha256": "cef7044679538bac7b01ca96a23f586c3cabb75cdff67590b278ab3ba2eb3e9b",
40
- "size": 16794
38
+ "url": "signet-connectors-0.185.5.tar.gz",
39
+ "sha256": "7505ac398e4aa655255bc19dc0026097e5354fcfa48e3e2ebff25026d8784422",
40
+ "size": 16888
41
41
  }
42
42
  }
43
43
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signetai",
3
- "version": "0.185.3",
3
+ "version": "0.185.5",
4
4
  "description": "Signet native CLI installer wrapper",
5
5
  "type": "module",
6
6
  "bin": {
@@ -65,10 +65,10 @@
65
65
  "access": "public"
66
66
  },
67
67
  "optionalDependencies": {
68
- "signetai-darwin-arm64": "https://github.com/Signet-AI/signetai/releases/download/v0.185.3/signetai-darwin-arm64-0.185.3.tgz",
69
- "signetai-darwin-x64": "https://github.com/Signet-AI/signetai/releases/download/v0.185.3/signetai-darwin-x64-0.185.3.tgz",
70
- "signetai-linux-arm64": "https://github.com/Signet-AI/signetai/releases/download/v0.185.3/signetai-linux-arm64-0.185.3.tgz",
71
- "signetai-linux-x64": "https://github.com/Signet-AI/signetai/releases/download/v0.185.3/signetai-linux-x64-0.185.3.tgz",
72
- "signetai-win32-x64": "https://github.com/Signet-AI/signetai/releases/download/v0.185.3/signetai-win32-x64-0.185.3.tgz"
68
+ "signetai-darwin-arm64": "https://github.com/Signet-AI/signetai/releases/download/v0.185.5/signetai-darwin-arm64-0.185.5.tgz",
69
+ "signetai-darwin-x64": "https://github.com/Signet-AI/signetai/releases/download/v0.185.5/signetai-darwin-x64-0.185.5.tgz",
70
+ "signetai-linux-arm64": "https://github.com/Signet-AI/signetai/releases/download/v0.185.5/signetai-linux-arm64-0.185.5.tgz",
71
+ "signetai-linux-x64": "https://github.com/Signet-AI/signetai/releases/download/v0.185.5/signetai-linux-x64-0.185.5.tgz",
72
+ "signetai-win32-x64": "https://github.com/Signet-AI/signetai/releases/download/v0.185.5/signetai-win32-x64-0.185.5.tgz"
73
73
  }
74
74
  }