signetai 0.165.0 → 0.167.0
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 +180 -31
- package/native-manifest.json +14 -14
- package/package.json +6 -6
package/dist/mcp-stdio.js
CHANGED
|
@@ -36494,6 +36494,7 @@ function classifyEntityQuality(name, type) {
|
|
|
36494
36494
|
}
|
|
36495
36495
|
|
|
36496
36496
|
// ../../platform/daemon/src/episodic-sources.ts
|
|
36497
|
+
var EPISODIC_CAPTURED_AT_FLOOR = "2000-01-01T00:00:00.000Z";
|
|
36497
36498
|
function readNonEmptyTrimmed(value) {
|
|
36498
36499
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
36499
36500
|
}
|
|
@@ -36699,11 +36700,8 @@ function searchEpisodicSources(db, params) {
|
|
|
36699
36700
|
const query = params.query.trim();
|
|
36700
36701
|
const limit = Math.max(1, Math.min(Math.floor(params.limit ?? 20), 50));
|
|
36701
36702
|
const like = `%${query}%`;
|
|
36702
|
-
const
|
|
36703
|
-
|
|
36704
|
-
timeArgs.push(params.since);
|
|
36705
|
-
if (params.before !== undefined)
|
|
36706
|
-
timeArgs.push(params.before);
|
|
36703
|
+
const sinceArgs = params.since !== undefined ? [params.since, EPISODIC_CAPTURED_AT_FLOOR] : [];
|
|
36704
|
+
const beforeArgs = params.before !== undefined ? [params.before] : [];
|
|
36707
36705
|
const branches = [];
|
|
36708
36706
|
if (params.kind === undefined || params.kind === "memory") {
|
|
36709
36707
|
branches.push({
|
|
@@ -36712,8 +36710,9 @@ function searchEpisodicSources(db, params) {
|
|
|
36712
36710
|
WHERE agent_id = ? AND memory_kind = 'episodic'
|
|
36713
36711
|
AND COALESCE(is_deleted, 0) = 0 AND visibility != 'archived' AND scope IS NULL
|
|
36714
36712
|
AND COALESCE(type, '') != 'session_summary' AND content LIKE ?
|
|
36715
|
-
${params.since ? "AND created_at >= ?
|
|
36716
|
-
|
|
36713
|
+
${params.since ? "AND (julianday(created_at) >= julianday(?) OR julianday(created_at) < julianday(?))" : ""}
|
|
36714
|
+
${params.before ? "AND julianday(created_at) <= julianday(?)" : ""}`,
|
|
36715
|
+
args: [params.agentId, like, ...sinceArgs, ...beforeArgs]
|
|
36717
36716
|
});
|
|
36718
36717
|
}
|
|
36719
36718
|
if (params.kind === undefined || params.kind === "artifact") {
|
|
@@ -36722,7 +36721,8 @@ function searchEpisodicSources(db, params) {
|
|
|
36722
36721
|
FROM memory_artifacts ma
|
|
36723
36722
|
WHERE ma.agent_id = ? AND COALESCE(ma.is_deleted, 0) = 0
|
|
36724
36723
|
AND length(ma.content) > 0 AND ma.content LIKE ?
|
|
36725
|
-
${params.since ? "AND ma.captured_at >= ?
|
|
36724
|
+
${params.since ? "AND (julianday(ma.captured_at) >= julianday(?) OR julianday(ma.captured_at) < julianday(?))" : ""}
|
|
36725
|
+
${params.before ? "AND julianday(ma.captured_at) <= julianday(?)" : ""}
|
|
36726
36726
|
AND (ma.source_sha256 IS NULL OR ma.source_sha256 = ''
|
|
36727
36727
|
OR (ma.agent_id, ma.source_path) = (
|
|
36728
36728
|
SELECT ma2.agent_id, ma2.source_path FROM memory_artifacts ma2
|
|
@@ -36731,7 +36731,7 @@ function searchEpisodicSources(db, params) {
|
|
|
36731
36731
|
ORDER BY ma2.captured_at DESC, ma2.source_path ASC
|
|
36732
36732
|
LIMIT 1
|
|
36733
36733
|
))`,
|
|
36734
|
-
args: [params.agentId, like, ...
|
|
36734
|
+
args: [params.agentId, like, ...sinceArgs, ...beforeArgs]
|
|
36735
36735
|
});
|
|
36736
36736
|
}
|
|
36737
36737
|
if (params.kind === undefined || params.kind === "transcript") {
|
|
@@ -36739,9 +36739,9 @@ function searchEpisodicSources(db, params) {
|
|
|
36739
36739
|
sql: `SELECT 'transcript' AS kind, session_key AS id, COALESCE(updated_at, created_at) AS captured_at
|
|
36740
36740
|
FROM session_transcripts
|
|
36741
36741
|
WHERE agent_id = ? AND content LIKE ?
|
|
36742
|
-
${params.since ? "AND COALESCE(updated_at, created_at) >= ?" : ""}
|
|
36743
|
-
${params.before ? "AND COALESCE(updated_at, created_at) <= ?" : ""}`,
|
|
36744
|
-
args: [params.agentId, 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(?)" : ""}`,
|
|
36744
|
+
args: [params.agentId, like, ...sinceArgs, ...beforeArgs]
|
|
36745
36745
|
});
|
|
36746
36746
|
}
|
|
36747
36747
|
if (params.kind === undefined || params.kind === "summary") {
|
|
@@ -36751,8 +36751,9 @@ function searchEpisodicSources(db, params) {
|
|
|
36751
36751
|
WHERE agent_id = ? AND depth = 0
|
|
36752
36752
|
AND COALESCE(source_type, 'summary') IN ('summary', 'compaction', 'checkpoint')
|
|
36753
36753
|
AND content LIKE ?
|
|
36754
|
-
${params.since ? "AND latest_at >= ?
|
|
36755
|
-
|
|
36754
|
+
${params.since ? "AND (julianday(latest_at) >= julianday(?) OR julianday(latest_at) < julianday(?))" : ""}
|
|
36755
|
+
${params.before ? "AND julianday(latest_at) <= julianday(?)" : ""}`,
|
|
36756
|
+
args: [params.agentId, like, ...sinceArgs, ...beforeArgs]
|
|
36756
36757
|
});
|
|
36757
36758
|
}
|
|
36758
36759
|
const union3 = branches.map((branch) => branch.sql).join(`
|
|
@@ -43926,6 +43927,7 @@ function buildRememberRequestBody(content, options = {}) {
|
|
|
43926
43927
|
validUntil: options.validUntil,
|
|
43927
43928
|
sourceCreatedAt: options.sourceCreatedAt,
|
|
43928
43929
|
reviewAfter: options.reviewAfter,
|
|
43930
|
+
supersedes: options.supersedes,
|
|
43929
43931
|
hints: options.hints,
|
|
43930
43932
|
transcript: options.transcript,
|
|
43931
43933
|
structured: normalizeStructuredMemoryPayload(options.structured),
|
|
@@ -48289,6 +48291,7 @@ var ONTOLOGY_PROPOSAL_OPERATIONS = [
|
|
|
48289
48291
|
"update_link",
|
|
48290
48292
|
"archive_link",
|
|
48291
48293
|
"merge_entities",
|
|
48294
|
+
"merge_aspects",
|
|
48292
48295
|
"supersede_claim_value",
|
|
48293
48296
|
"create_policy",
|
|
48294
48297
|
"create_action_type",
|
|
@@ -49357,6 +49360,7 @@ function truncateToTokens(text, limit) {
|
|
|
49357
49360
|
}
|
|
49358
49361
|
|
|
49359
49362
|
// ../../platform/daemon/src/pipeline/dreaming.ts
|
|
49363
|
+
var EVIDENCE_WATERMARK_FLOOR_MS = Date.parse(EPISODIC_CAPTURED_AT_FLOOR);
|
|
49360
49364
|
var FAILURE_BACKOFF_BASE_MS = 5 * 60 * 1000;
|
|
49361
49365
|
var DREAMING_HALT_COOLDOWN_MS = 24 * 60 * 60 * 1000;
|
|
49362
49366
|
|
|
@@ -50051,8 +50055,10 @@ var DEFAULT_PIPELINE_V2 = {
|
|
|
50051
50055
|
traversal: {
|
|
50052
50056
|
enabled: true,
|
|
50053
50057
|
primary: true,
|
|
50054
|
-
maxAspectsPerEntity:
|
|
50055
|
-
maxAttributesPerAspect:
|
|
50058
|
+
maxAspectsPerEntity: 20,
|
|
50059
|
+
maxAttributesPerAspect: 50,
|
|
50060
|
+
maxWriteAspectsPerEntity: 20,
|
|
50061
|
+
maxWriteAttributesPerAspect: 50,
|
|
50056
50062
|
maxDependencyHops: 10,
|
|
50057
50063
|
minDependencyStrength: 0.3,
|
|
50058
50064
|
maxBranching: 4,
|
|
@@ -50821,6 +50827,15 @@ function txSupersedeMemory(db, input) {
|
|
|
50821
50827
|
currentSupersededBy: existing.superseded_by
|
|
50822
50828
|
};
|
|
50823
50829
|
}
|
|
50830
|
+
if (existing.superseded_by !== null && existing.superseded_by !== input.supersededBy) {
|
|
50831
|
+
return {
|
|
50832
|
+
status: "already_superseded_by_other",
|
|
50833
|
+
memoryId: input.memoryId,
|
|
50834
|
+
supersededBy: existing.superseded_by,
|
|
50835
|
+
currentVersion: existing.version,
|
|
50836
|
+
currentSupersededBy: existing.superseded_by
|
|
50837
|
+
};
|
|
50838
|
+
}
|
|
50824
50839
|
const target2 = db.prepare(`SELECT id, is_deleted, agent_id, project, scope, visibility
|
|
50825
50840
|
FROM memories
|
|
50826
50841
|
WHERE id = ?`).get(input.supersededBy);
|
|
@@ -50893,7 +50908,7 @@ function applyOntologyOperationBatchInTx(db, params) {
|
|
|
50893
50908
|
const row = getProposalInTx(db, inserted.id, params.agentId);
|
|
50894
50909
|
if (row === null)
|
|
50895
50910
|
throw new OntologyProposalError("Proposal not found", 404);
|
|
50896
|
-
const result = applyOperation(db, row, params.actor);
|
|
50911
|
+
const result = applyOperation(db, row, params.actor, params.writeCaps);
|
|
50897
50912
|
items.push({
|
|
50898
50913
|
proposal: markAppliedInTx(db, row, params.actor, result),
|
|
50899
50914
|
result,
|
|
@@ -51355,7 +51370,7 @@ function restoreAttributeMemoryInTx(db, memoryId, proposal) {
|
|
|
51355
51370
|
createdAt: changedAt
|
|
51356
51371
|
});
|
|
51357
51372
|
}
|
|
51358
|
-
function applyAddClaimValue(db, agentId, proposal, payload) {
|
|
51373
|
+
function applyAddClaimValue(db, agentId, proposal, payload, writeCaps) {
|
|
51359
51374
|
const entity = readString2(payload, "entity");
|
|
51360
51375
|
const aspect = readString2(payload, "aspect");
|
|
51361
51376
|
const claimKey = readString2(payload, "claim_key");
|
|
@@ -51369,6 +51384,9 @@ function applyAddClaimValue(db, agentId, proposal, payload) {
|
|
|
51369
51384
|
if (value === null)
|
|
51370
51385
|
throw new OntologyProposalError("payload.value is required", 400);
|
|
51371
51386
|
const entityId = resolveOrCreateEntity(db, agentId, entity, normalizeEntityType2(readString2(payload, "entity_type")));
|
|
51387
|
+
const addEntityRow = db.prepare("SELECT id, name FROM entities WHERE id = ?").get(entityId);
|
|
51388
|
+
if (addEntityRow !== undefined)
|
|
51389
|
+
enforceAspectCapForNewAspect(db, addEntityRow, agentId, aspect, writeCaps);
|
|
51372
51390
|
const aspectId = resolveOrCreateAspect(db, entityId, agentId, aspect);
|
|
51373
51391
|
const groupKey = readString2(payload, "group_key") ?? "general";
|
|
51374
51392
|
const kind = normalizeAttributeKind(readString2(payload, "kind"));
|
|
@@ -51385,6 +51403,14 @@ function applyAddClaimValue(db, agentId, proposal, payload) {
|
|
|
51385
51403
|
if (existing) {
|
|
51386
51404
|
return { entityId, aspectId, attributeId: existing.id, deduped: true };
|
|
51387
51405
|
}
|
|
51406
|
+
if (writeCaps !== undefined) {
|
|
51407
|
+
const attrCount = db.prepare(`SELECT COUNT(*) AS c FROM entity_attributes
|
|
51408
|
+
WHERE aspect_id = ? AND agent_id = ? AND status = 'active'`).get(aspectId, agentId);
|
|
51409
|
+
if (attrCount.c >= writeCaps.maxAttributesPerAspect) {
|
|
51410
|
+
const aspectName = db.prepare("SELECT name FROM entity_aspects WHERE id = ?").get(aspectId);
|
|
51411
|
+
throw new OntologyProposalError(`aspect '${aspectName?.name ?? aspectId}' is at attribute cap (${attrCount.c}/${writeCaps.maxAttributesPerAspect}) — supersede or expire an existing claim, or consolidate duplicates, before adding`, 409);
|
|
51412
|
+
}
|
|
51413
|
+
}
|
|
51388
51414
|
const id = crypto.randomUUID();
|
|
51389
51415
|
const confidence = clamp01(readNumber(payload, "confidence") ?? proposal.confidence);
|
|
51390
51416
|
const importance = clamp01(readNumber(payload, "importance") ?? confidence);
|
|
@@ -51411,7 +51437,7 @@ function applyAddClaimValue(db, agentId, proposal, payload) {
|
|
|
51411
51437
|
});
|
|
51412
51438
|
return { entityId, aspectId, attributeId: id, memoryId, deduped: false };
|
|
51413
51439
|
}
|
|
51414
|
-
function applySetClaimValue(db, agentId, proposal, payload) {
|
|
51440
|
+
function applySetClaimValue(db, agentId, proposal, payload, writeCaps) {
|
|
51415
51441
|
const entity = readString2(payload, "entity");
|
|
51416
51442
|
const aspect = readString2(payload, "aspect");
|
|
51417
51443
|
const claimKey = canonicalKey(readString2(payload, "claim_key") ?? readString2(payload, "claim"));
|
|
@@ -51453,6 +51479,14 @@ function applySetClaimValue(db, agentId, proposal, payload) {
|
|
|
51453
51479
|
throw new OntologyProposalError("Refusing to replace active constraint claim without force", 409);
|
|
51454
51480
|
}
|
|
51455
51481
|
const previous = active[0] ?? slot[0] ?? null;
|
|
51482
|
+
if (previous === null && writeCaps !== undefined) {
|
|
51483
|
+
const attrCount = db.prepare(`SELECT COUNT(*) AS c FROM entity_attributes
|
|
51484
|
+
WHERE aspect_id = ? AND agent_id = ? AND status = 'active'`).get(aspectId, agentId);
|
|
51485
|
+
if (attrCount.c >= writeCaps.maxAttributesPerAspect) {
|
|
51486
|
+
const aspectName = db.prepare("SELECT name FROM entity_aspects WHERE id = ?").get(aspectId);
|
|
51487
|
+
throw new OntologyProposalError(`aspect '${aspectName?.name ?? aspectId}' is at attribute cap (${attrCount.c}/${writeCaps.maxAttributesPerAspect}) — supersede or expire an existing claim, or consolidate duplicates, before adding`, 409);
|
|
51488
|
+
}
|
|
51489
|
+
}
|
|
51456
51490
|
const version2 = previous === null ? 1 : Math.max(...slot.map((row) => row.version ?? 1)) + 1;
|
|
51457
51491
|
const rootId = previous?.version_root_id ?? previous?.id ?? crypto.randomUUID();
|
|
51458
51492
|
const id = version2 === 1 ? rootId : crypto.randomUUID();
|
|
@@ -51624,7 +51658,21 @@ function applyArchiveEntity(db, agentId, proposal, payload, actor) {
|
|
|
51624
51658
|
WHERE id = ? AND agent_id = ?`).run(actor, readString2(payload, "reason") ?? proposal.rationale, proposal.id, JSON.stringify(proposalAuditEvidence(proposal)), entity.id, agentId);
|
|
51625
51659
|
return { entityId: entity.id, archived: true };
|
|
51626
51660
|
}
|
|
51627
|
-
function
|
|
51661
|
+
function enforceAspectCapForNewAspect(db, entity, agentId, name, writeCaps) {
|
|
51662
|
+
if (writeCaps === undefined)
|
|
51663
|
+
return;
|
|
51664
|
+
const key = canonical(name);
|
|
51665
|
+
const activeAspect = db.prepare(`SELECT id FROM entity_aspects
|
|
51666
|
+
WHERE entity_id = ? AND agent_id = ? AND canonical_name = ? AND COALESCE(status, 'active') = 'active'`).get(entity.id, agentId, key);
|
|
51667
|
+
if (activeAspect != null)
|
|
51668
|
+
return;
|
|
51669
|
+
const aspectCount = db.prepare(`SELECT COUNT(*) AS c FROM entity_aspects
|
|
51670
|
+
WHERE entity_id = ? AND agent_id = ? AND COALESCE(status, 'active') = 'active'`).get(entity.id, agentId);
|
|
51671
|
+
if (aspectCount.c >= writeCaps.maxAspectsPerEntity) {
|
|
51672
|
+
throw new OntologyProposalError(`entity '${entity.name}' is at aspect cap (${aspectCount.c}/${writeCaps.maxAspectsPerEntity}) — consolidate or archive an existing aspect before creating a new one`, 409);
|
|
51673
|
+
}
|
|
51674
|
+
}
|
|
51675
|
+
function applyCreateAspect(db, agentId, proposal, payload, writeCaps) {
|
|
51628
51676
|
const entitySelector = readPayloadSelector(payload, "entity", "entity_id");
|
|
51629
51677
|
const name = readString2(payload, "name") ?? readString2(payload, "aspect");
|
|
51630
51678
|
if (entitySelector === null)
|
|
@@ -51632,6 +51680,7 @@ function applyCreateAspect(db, agentId, proposal, payload) {
|
|
|
51632
51680
|
if (name === null)
|
|
51633
51681
|
throw new OntologyProposalError("payload.name is required", 400);
|
|
51634
51682
|
const entity = resolveEntityStrict(db, agentId, entitySelector);
|
|
51683
|
+
enforceAspectCapForNewAspect(db, entity, agentId, name, writeCaps);
|
|
51635
51684
|
const aspectId = resolveOrCreateAspect(db, entity.id, agentId, name);
|
|
51636
51685
|
db.prepare(`UPDATE entity_aspects
|
|
51637
51686
|
SET proposal_id = ?, proposal_evidence = ?, updated_at = datetime('now')
|
|
@@ -51795,6 +51844,68 @@ function applyMergeEntities(db, agentId, payload) {
|
|
|
51795
51844
|
warnings: plan.warnings
|
|
51796
51845
|
};
|
|
51797
51846
|
}
|
|
51847
|
+
function applyMergeAspects(db, agentId, proposal, payload) {
|
|
51848
|
+
const entitySelector = readPayloadSelector(payload, "entity", "entity_id");
|
|
51849
|
+
const targetSelector = readPayloadSelector(payload, "target", "target_aspect", "target_aspect_id", "aspect");
|
|
51850
|
+
const rawSources = readStringArray(payload, "sources") ?? readStringArray(payload, "source_aspects");
|
|
51851
|
+
if (entitySelector === null)
|
|
51852
|
+
throw new OntologyProposalError("payload.entity is required", 400);
|
|
51853
|
+
if (targetSelector === null)
|
|
51854
|
+
throw new OntologyProposalError("payload.target is required", 400);
|
|
51855
|
+
if (rawSources.length === 0)
|
|
51856
|
+
throw new OntologyProposalError("payload.sources is required", 400);
|
|
51857
|
+
const entity = resolveEntityStrict(db, agentId, entitySelector);
|
|
51858
|
+
const target2 = resolveAspectStrict(db, agentId, entity.id, targetSelector);
|
|
51859
|
+
const newName = readString2(payload, "new_name");
|
|
51860
|
+
if (newName !== null) {
|
|
51861
|
+
const key = canonical(newName);
|
|
51862
|
+
const collision = db.prepare(`SELECT id FROM entity_aspects
|
|
51863
|
+
WHERE entity_id = ? AND agent_id = ? AND id != ?
|
|
51864
|
+
AND COALESCE(status, 'active') = 'active'
|
|
51865
|
+
AND (canonical_name = ? OR LOWER(name) = ?)
|
|
51866
|
+
LIMIT 1`).get(entity.id, agentId, target2.id, key, key);
|
|
51867
|
+
if (collision)
|
|
51868
|
+
throw new OntologyProposalError(`Aspect collides with "${newName}"`, 409);
|
|
51869
|
+
}
|
|
51870
|
+
const evidence = JSON.stringify(proposalAuditEvidence(proposal));
|
|
51871
|
+
const moved = [];
|
|
51872
|
+
let totalMoved = 0;
|
|
51873
|
+
const seen = new Set([target2.id]);
|
|
51874
|
+
for (const raw of rawSources) {
|
|
51875
|
+
if (typeof raw !== "string")
|
|
51876
|
+
throw new OntologyProposalError("payload.sources must be aspect selectors", 400);
|
|
51877
|
+
const source = resolveAspectStrict(db, agentId, entity.id, raw);
|
|
51878
|
+
if (seen.has(source.id))
|
|
51879
|
+
continue;
|
|
51880
|
+
seen.add(source.id);
|
|
51881
|
+
const attributes = db.prepare("SELECT id FROM entity_attributes WHERE aspect_id = ? AND agent_id = ?").all(source.id, agentId);
|
|
51882
|
+
for (const attribute of attributes) {
|
|
51883
|
+
db.prepare(`UPDATE entity_attributes
|
|
51884
|
+
SET aspect_id = ?, updated_at = datetime('now')
|
|
51885
|
+
WHERE id = ? AND agent_id = ?`).run(target2.id, attribute.id, agentId);
|
|
51886
|
+
}
|
|
51887
|
+
db.prepare(`UPDATE entity_aspects
|
|
51888
|
+
SET status = 'archived', archived_at = datetime('now'), archived_by = ?,
|
|
51889
|
+
archive_reason = ?, proposal_id = ?, proposal_evidence = ?, updated_at = datetime('now')
|
|
51890
|
+
WHERE id = ? AND agent_id = ? AND COALESCE(status, 'active') = 'active'`).run(proposal.created_by || "ontology-merge", `Merged into aspect '${target2.name}'`, proposal.id, evidence, source.id, agentId);
|
|
51891
|
+
moved.push({ aspect: source.name, attributes: attributes.length });
|
|
51892
|
+
totalMoved += attributes.length;
|
|
51893
|
+
}
|
|
51894
|
+
if (moved.length === 0)
|
|
51895
|
+
throw new OntologyProposalError("No distinct source aspects to merge", 400);
|
|
51896
|
+
if (newName !== null) {
|
|
51897
|
+
db.prepare(`UPDATE entity_aspects
|
|
51898
|
+
SET name = ?, canonical_name = ?, proposal_id = ?, proposal_evidence = ?, updated_at = datetime('now')
|
|
51899
|
+
WHERE id = ? AND agent_id = ?`).run(newName, canonical(newName), proposal.id, evidence, target2.id, agentId);
|
|
51900
|
+
}
|
|
51901
|
+
return {
|
|
51902
|
+
entityId: entity.id,
|
|
51903
|
+
targetAspectId: target2.id,
|
|
51904
|
+
targetAspect: newName ?? target2.name,
|
|
51905
|
+
mergedAspects: moved,
|
|
51906
|
+
totalAttributesMoved: totalMoved
|
|
51907
|
+
};
|
|
51908
|
+
}
|
|
51798
51909
|
function applyCreateLink(db, agentId, proposal, payload) {
|
|
51799
51910
|
const sourceIdSelector = readString2(payload, "source_entity_id");
|
|
51800
51911
|
const targetIdSelector = readString2(payload, "target_entity_id");
|
|
@@ -51927,7 +52038,7 @@ function applyArchiveEntityAlias(db, agentId, proposal, payload) {
|
|
|
51927
52038
|
throw new OntologyProposalError("Alias not found", 404);
|
|
51928
52039
|
return { aliasId, entityId: entity.id, archived: true };
|
|
51929
52040
|
}
|
|
51930
|
-
function applyOperation(db, proposal, actor) {
|
|
52041
|
+
function applyOperation(db, proposal, actor, writeCaps) {
|
|
51931
52042
|
const payload = parseJsonRecord(proposal.payload);
|
|
51932
52043
|
if (proposal.operation === "create_entity")
|
|
51933
52044
|
return applyCreateEntity(db, proposal.agent_id, proposal, payload);
|
|
@@ -51936,17 +52047,19 @@ function applyOperation(db, proposal, actor) {
|
|
|
51936
52047
|
if (proposal.operation === "archive_entity")
|
|
51937
52048
|
return applyArchiveEntity(db, proposal.agent_id, proposal, payload, actor);
|
|
51938
52049
|
if (proposal.operation === "create_aspect")
|
|
51939
|
-
return applyCreateAspect(db, proposal.agent_id, proposal, payload);
|
|
52050
|
+
return applyCreateAspect(db, proposal.agent_id, proposal, payload, writeCaps);
|
|
51940
52051
|
if (proposal.operation === "rename_aspect")
|
|
51941
52052
|
return applyRenameAspect(db, proposal.agent_id, proposal, payload);
|
|
51942
52053
|
if (proposal.operation === "archive_aspect")
|
|
51943
52054
|
return applyArchiveAspect(db, proposal.agent_id, proposal, payload, actor);
|
|
51944
52055
|
if (proposal.operation === "add_claim_value")
|
|
51945
|
-
return applyAddClaimValue(db, proposal.agent_id, proposal, payload);
|
|
52056
|
+
return applyAddClaimValue(db, proposal.agent_id, proposal, payload, writeCaps);
|
|
51946
52057
|
if (proposal.operation === "set_claim_value")
|
|
51947
|
-
return applySetClaimValue(db, proposal.agent_id, proposal, payload);
|
|
52058
|
+
return applySetClaimValue(db, proposal.agent_id, proposal, payload, writeCaps);
|
|
51948
52059
|
if (proposal.operation === "merge_entities")
|
|
51949
52060
|
return applyMergeEntities(db, proposal.agent_id, payload);
|
|
52061
|
+
if (proposal.operation === "merge_aspects")
|
|
52062
|
+
return applyMergeAspects(db, proposal.agent_id, proposal, payload);
|
|
51950
52063
|
if (proposal.operation === "supersede_claim_value") {
|
|
51951
52064
|
return applySupersedeClaimValue(db, proposal.agent_id, proposal, payload);
|
|
51952
52065
|
}
|
|
@@ -52385,6 +52498,13 @@ var DREAMING_ONTOLOGY_PAYLOAD_SCHEMAS = {
|
|
|
52385
52498
|
survivor: entityId.describe("The entity that survives the merge."),
|
|
52386
52499
|
...reasonField
|
|
52387
52500
|
}),
|
|
52501
|
+
merge_aspects: payload({
|
|
52502
|
+
entityId,
|
|
52503
|
+
target: aspectId.describe("The aspect that absorbs the sources. Use aspect_id."),
|
|
52504
|
+
sources: exports_external.array(aspectId).min(1).describe("Aspect ids to fold into the target. Attributes are moved, sources are archived."),
|
|
52505
|
+
newName: aspectName.describe("Optional new name for the merged aspect.").optional(),
|
|
52506
|
+
...reasonField
|
|
52507
|
+
}),
|
|
52388
52508
|
create_entity: payload({ name: entityName, type: entityType }),
|
|
52389
52509
|
add_claim_value: payload({ entityId, aspectId, claimKey, value: claimValue, reviewAfter }),
|
|
52390
52510
|
set_claim_value: payload({ entityId, aspectId, claimKey, value: claimValue, reviewAfter }),
|
|
@@ -52440,6 +52560,7 @@ var DREAMING_ONTOLOGY_OPERATION_SCHEMA = exports_external.discriminatedUnion("op
|
|
|
52440
52560
|
operation("update_link"),
|
|
52441
52561
|
operation("archive_link"),
|
|
52442
52562
|
operation("merge_entities"),
|
|
52563
|
+
operation("merge_aspects"),
|
|
52443
52564
|
operation("supersede_claim_value"),
|
|
52444
52565
|
operation("create_policy"),
|
|
52445
52566
|
operation("create_action_type"),
|
|
@@ -52454,7 +52575,8 @@ var HYGIENE_ARCHIVE_OPS = new Set([
|
|
|
52454
52575
|
"archive_aspect",
|
|
52455
52576
|
"archive_claim_value",
|
|
52456
52577
|
"archive_link",
|
|
52457
|
-
"merge_entities"
|
|
52578
|
+
"merge_entities",
|
|
52579
|
+
"merge_aspects"
|
|
52458
52580
|
]);
|
|
52459
52581
|
function citationRecord(value) {
|
|
52460
52582
|
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
@@ -52569,6 +52691,10 @@ function attentionProvenance(accessor, agentId, operation2, mintedById) {
|
|
|
52569
52691
|
const survivor = typeof payload2.survivor === "string" ? payload2.survivor : "";
|
|
52570
52692
|
const groupIds = semanticDuplicateIds(accessor, agentId, attention.details.canonicalName ?? "");
|
|
52571
52693
|
expectedTarget = attention.subjectRef === `duplicate:${attention.details.canonicalName}` && groupIds.size > 1 && groupIds.has(survivor) && targets.length >= 2 && targets.every((id) => groupIds.has(id)) && targets.includes(survivor) && targets.some((id) => id !== survivor);
|
|
52694
|
+
} else if (operation2.operation === "merge_aspects") {
|
|
52695
|
+
const sources = Array.isArray(payload2.sources) ? payload2.sources.filter((value) => typeof value === "string") : [];
|
|
52696
|
+
const flaggedAspect = attention.details.aspectId ?? attention.subjectRef.replace(/^aspect:/, "");
|
|
52697
|
+
expectedTarget = attention.subjectRef.startsWith("aspect:") && typeof payload2.target === "string" && sources.length >= 1 && sources.includes(flaggedAspect);
|
|
52572
52698
|
}
|
|
52573
52699
|
if (!expectedTarget)
|
|
52574
52700
|
return null;
|
|
@@ -52675,6 +52801,15 @@ function toApplicatorPayload(accessor, agentId, operation2, payload2) {
|
|
|
52675
52801
|
const sourceIds = targets.filter((id) => id !== survivor);
|
|
52676
52802
|
return { target_entity_id: survivor, source_entity_ids: sourceIds };
|
|
52677
52803
|
}
|
|
52804
|
+
case "merge_aspects": {
|
|
52805
|
+
const entityId2 = stringField(payload2, "entityId");
|
|
52806
|
+
const target3 = stringField(payload2, "target");
|
|
52807
|
+
const sources = stringArrayField(payload2, "sources");
|
|
52808
|
+
if (entityId2 === null || target3 === null || sources === null || sources.length === 0)
|
|
52809
|
+
return null;
|
|
52810
|
+
const name = lookupEntityName(accessor, agentId, entityId2);
|
|
52811
|
+
return name === null ? null : { entity: name, target: target3, sources, new_name: stringField(payload2, "newName") ?? undefined };
|
|
52812
|
+
}
|
|
52678
52813
|
case "create_entity": {
|
|
52679
52814
|
const name = stringField(payload2, "name");
|
|
52680
52815
|
const type = stringField(payload2, "type");
|
|
@@ -52836,7 +52971,8 @@ function applyDreamingOperations(params) {
|
|
|
52836
52971
|
const batch = applyOntologyOperationBatchInTx(db, {
|
|
52837
52972
|
agentId: params.agentId,
|
|
52838
52973
|
actor: params.actor,
|
|
52839
|
-
operations: [entry.input]
|
|
52974
|
+
operations: [entry.input],
|
|
52975
|
+
writeCaps: params.writeCaps
|
|
52840
52976
|
});
|
|
52841
52977
|
db.exec(`RELEASE SAVEPOINT ${savepoint}`);
|
|
52842
52978
|
if (entry.attentionId !== null) {
|
|
@@ -53059,6 +53195,14 @@ function boundedText(value, maxChars) {
|
|
|
53059
53195
|
return value;
|
|
53060
53196
|
return value.slice(0, maxChars);
|
|
53061
53197
|
}
|
|
53198
|
+
function readEvidenceWatermark(db, agentId) {
|
|
53199
|
+
try {
|
|
53200
|
+
const row = db.prepare("SELECT last_pass_at AS lastPassAt FROM dreaming_state WHERE agent_id = ?").get(agentId);
|
|
53201
|
+
return row?.lastPassAt ?? null;
|
|
53202
|
+
} catch {
|
|
53203
|
+
return null;
|
|
53204
|
+
}
|
|
53205
|
+
}
|
|
53062
53206
|
function evidenceExcerptStart(content, query, maxChars) {
|
|
53063
53207
|
const terms = query.toLowerCase().split(/\W+/).filter((term) => term.length >= 3).slice(0, 8);
|
|
53064
53208
|
const lower = content.toLowerCase();
|
|
@@ -53291,7 +53435,7 @@ function createDreamingCapabilities(params) {
|
|
|
53291
53435
|
}
|
|
53292
53436
|
return { ok: true, result: getOntologyLinkEvidence(accessor, { agentId: scopeId, id: ref3.id }) };
|
|
53293
53437
|
}),
|
|
53294
|
-
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 to list the
|
|
53438
|
+
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({
|
|
53295
53439
|
agentId: exports_external.string().min(1),
|
|
53296
53440
|
query: exports_external.string().optional(),
|
|
53297
53441
|
since: exports_external.string().optional(),
|
|
@@ -53309,10 +53453,11 @@ function createDreamingCapabilities(params) {
|
|
|
53309
53453
|
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));
|
|
53310
53454
|
return fragment === null ? { ok: false, error: "Evidence fragment offset is outside the source" } : { ok: true, items: [fragment] };
|
|
53311
53455
|
}
|
|
53456
|
+
const effectiveSince = since ?? readEvidenceWatermark(db, scopeId);
|
|
53312
53457
|
const sources = searchEpisodicSources(db, {
|
|
53313
53458
|
agentId: scopeId,
|
|
53314
53459
|
query: query ?? "",
|
|
53315
|
-
since,
|
|
53460
|
+
since: effectiveSince ?? undefined,
|
|
53316
53461
|
before,
|
|
53317
53462
|
kind,
|
|
53318
53463
|
limit
|
|
@@ -53420,7 +53565,8 @@ function createDreamingCapabilities(params) {
|
|
|
53420
53565
|
agentId: scopeId,
|
|
53421
53566
|
actor,
|
|
53422
53567
|
operations,
|
|
53423
|
-
passId: params.passId
|
|
53568
|
+
passId: params.passId,
|
|
53569
|
+
writeCaps: params.writeCaps
|
|
53424
53570
|
});
|
|
53425
53571
|
params.onOperationsApplied?.(result, operations);
|
|
53426
53572
|
return { ok: result.ok, ...result.error ? { error: result.error } : {}, items: result.items };
|
|
@@ -55463,6 +55609,7 @@ async function createMcpServer(opts) {
|
|
|
55463
55609
|
validFrom: exports_external.string().optional().describe("Start of validity window for this memory"),
|
|
55464
55610
|
validUntil: exports_external.string().optional().describe("End of validity window for this memory"),
|
|
55465
55611
|
reviewAfter: exports_external.string().optional().describe("ISO timestamp when this temporal claim becomes due for review (issue #945)"),
|
|
55612
|
+
supersedes: exports_external.string().optional().describe("Id of an existing memory this write supersedes. The old row is marked superseded in the same transaction, wiring vN -> vN+1 lineage for drill-down history."),
|
|
55466
55613
|
transcript: exports_external.string().optional().describe("Raw source text (conversation transcript) to preserve alongside extracted memory"),
|
|
55467
55614
|
structured: exports_external.object({
|
|
55468
55615
|
entities: exports_external.array(exports_external.object({
|
|
@@ -55515,7 +55662,8 @@ async function createMcpServer(opts) {
|
|
|
55515
55662
|
sourceCreatedAt,
|
|
55516
55663
|
validFrom,
|
|
55517
55664
|
validUntil,
|
|
55518
|
-
reviewAfter: reviewAfter2
|
|
55665
|
+
reviewAfter: reviewAfter2,
|
|
55666
|
+
supersedes
|
|
55519
55667
|
}) => {
|
|
55520
55668
|
const result = await fetchDaemon(baseUrl, "/api/memory/remember", {
|
|
55521
55669
|
method: "POST",
|
|
@@ -55533,7 +55681,8 @@ async function createMcpServer(opts) {
|
|
|
55533
55681
|
sourceCreatedAt,
|
|
55534
55682
|
validFrom,
|
|
55535
55683
|
validUntil,
|
|
55536
|
-
reviewAfter: reviewAfter2
|
|
55684
|
+
reviewAfter: reviewAfter2,
|
|
55685
|
+
supersedes
|
|
55537
55686
|
})
|
|
55538
55687
|
});
|
|
55539
55688
|
if (!result.ok) {
|
package/native-manifest.json
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.167.0",
|
|
4
4
|
"assets": [
|
|
5
5
|
{
|
|
6
6
|
"name": "signet-darwin-arm64",
|
|
7
7
|
"platform": "darwin-arm64",
|
|
8
|
-
"sha256": "
|
|
9
|
-
"size":
|
|
8
|
+
"sha256": "9873f32416ca55b9759d8470cfe5a074f4d91084bdd927f71be47f6c442611ba",
|
|
9
|
+
"size": 116962336
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"name": "signet-darwin-x64",
|
|
13
13
|
"platform": "darwin-x64",
|
|
14
|
-
"sha256": "
|
|
15
|
-
"size":
|
|
14
|
+
"sha256": "1d48388b93a7c87d042176c0671240b7e0782e54e98c9c0eed1301e55c0e94c8",
|
|
15
|
+
"size": 121588288
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
"name": "signet-linux-arm64",
|
|
19
19
|
"platform": "linux-arm64",
|
|
20
|
-
"sha256": "
|
|
21
|
-
"size":
|
|
20
|
+
"sha256": "5b226210a175550fa16f929e1cd488563460092e1799e90d8a2cfec19478dfc1",
|
|
21
|
+
"size": 154208710
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
24
|
"name": "signet-linux-x64",
|
|
25
25
|
"platform": "linux-x64",
|
|
26
|
-
"sha256": "
|
|
27
|
-
"size":
|
|
26
|
+
"sha256": "fde3e639c5c5e2a8c4b059d1792641ab9853a4d76340a24f9b391a1bf194abf4",
|
|
27
|
+
"size": 154767695
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
30
|
"name": "signet-win32-x64.exe",
|
|
31
31
|
"platform": "win32-x64",
|
|
32
|
-
"sha256": "
|
|
33
|
-
"size":
|
|
32
|
+
"sha256": "1b29614c6ab3f35cb0c5d8b582a68d7da15ce9371b93a0c1b796d41e48d6f616",
|
|
33
|
+
"size": 170900992
|
|
34
34
|
}
|
|
35
35
|
],
|
|
36
36
|
"components": {
|
|
37
37
|
"connectors": {
|
|
38
|
-
"url": "signet-connectors-0.
|
|
39
|
-
"sha256": "
|
|
40
|
-
"size":
|
|
38
|
+
"url": "signet-connectors-0.167.0.tar.gz",
|
|
39
|
+
"sha256": "ad0d2bba53e73dde4705fb5150ccc87a8b75bcdf8f71ab19bad2db45f373cdf9",
|
|
40
|
+
"size": 16250
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "signetai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.167.0",
|
|
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.
|
|
69
|
-
"signetai-darwin-x64": "https://github.com/Signet-AI/signetai/releases/download/v0.
|
|
70
|
-
"signetai-linux-arm64": "https://github.com/Signet-AI/signetai/releases/download/v0.
|
|
71
|
-
"signetai-linux-x64": "https://github.com/Signet-AI/signetai/releases/download/v0.
|
|
72
|
-
"signetai-win32-x64": "https://github.com/Signet-AI/signetai/releases/download/v0.
|
|
68
|
+
"signetai-darwin-arm64": "https://github.com/Signet-AI/signetai/releases/download/v0.167.0/signetai-darwin-arm64-0.167.0.tgz",
|
|
69
|
+
"signetai-darwin-x64": "https://github.com/Signet-AI/signetai/releases/download/v0.167.0/signetai-darwin-x64-0.167.0.tgz",
|
|
70
|
+
"signetai-linux-arm64": "https://github.com/Signet-AI/signetai/releases/download/v0.167.0/signetai-linux-arm64-0.167.0.tgz",
|
|
71
|
+
"signetai-linux-x64": "https://github.com/Signet-AI/signetai/releases/download/v0.167.0/signetai-linux-x64-0.167.0.tgz",
|
|
72
|
+
"signetai-win32-x64": "https://github.com/Signet-AI/signetai/releases/download/v0.167.0/signetai-win32-x64-0.167.0.tgz"
|
|
73
73
|
}
|
|
74
74
|
}
|