stratagate-dsh 0.2.69 → 0.2.71
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/CHANGELOG.md +11 -0
- package/dist/client.js +15 -5
- package/dist/plugin.js +206 -55
- package/dist/plugin.js.map +1 -1
- package/package.json +3 -3
package/dist/plugin.js
CHANGED
|
@@ -1314,8 +1314,9 @@ function normalizeRetrievalAssessment(input, batchEvidenceRefs) {
|
|
|
1314
1314
|
}
|
|
1315
1315
|
|
|
1316
1316
|
// packages/core/src/storage.ts
|
|
1317
|
-
var STRATAGATE_STORAGE_SCHEMA_VERSION =
|
|
1317
|
+
var STRATAGATE_STORAGE_SCHEMA_VERSION = 11;
|
|
1318
1318
|
var KNOWLEDGE_GRAPH_PROJECTOR_VERSION = 1;
|
|
1319
|
+
var DERIVATION_MAX_ATTEMPTS = 3;
|
|
1319
1320
|
var StorageConflictError = class extends Error {
|
|
1320
1321
|
constructor(namespace, expectedRevision, actualRevision) {
|
|
1321
1322
|
super(`Storage revision conflict for ${namespace}: expected ${expectedRevision}, found ${actualRevision ?? "missing"}`);
|
|
@@ -1448,6 +1449,11 @@ function normalizeSnapshot(value) {
|
|
|
1448
1449
|
schemaVersion: STRATAGATE_STORAGE_SCHEMA_VERSION,
|
|
1449
1450
|
externalMemoryImportJobs: []
|
|
1450
1451
|
};
|
|
1452
|
+
} else if (schemaVersion === 10) {
|
|
1453
|
+
snapshot = {
|
|
1454
|
+
...structuredClone(value),
|
|
1455
|
+
schemaVersion: STRATAGATE_STORAGE_SCHEMA_VERSION
|
|
1456
|
+
};
|
|
1451
1457
|
} else if (schemaVersion === STRATAGATE_STORAGE_SCHEMA_VERSION) {
|
|
1452
1458
|
snapshot = structuredClone(value);
|
|
1453
1459
|
} else {
|
|
@@ -1467,8 +1473,19 @@ function normalizeSnapshot(value) {
|
|
|
1467
1473
|
if (!Array.isArray(snapshot[key])) throw new TypeError(`Invalid StrataGate snapshot: ${key} must be an array`);
|
|
1468
1474
|
}
|
|
1469
1475
|
if (!Array.isArray(snapshot.successfulModelResponses)) snapshot.successfulModelResponses = [];
|
|
1476
|
+
for (const job of snapshot.graphProjectionJobs) {
|
|
1477
|
+
if (job.nextRetryAt === void 0) job.nextRetryAt = null;
|
|
1478
|
+
}
|
|
1479
|
+
const sourceBlockMap = new Map(snapshot.blocks.map((block) => [block.id, block]));
|
|
1470
1480
|
for (const event of snapshot.events) {
|
|
1471
1481
|
event.temporal = { ...event.temporal, eventType: normalizeStandardEventType(event.temporal.eventType) };
|
|
1482
|
+
if (event.formedTurn === void 0) {
|
|
1483
|
+
const sourceBlock = sourceBlockMap.get(event.sourceBlockId);
|
|
1484
|
+
const reliableSource = sourceBlock && !sourceBlock.threadId?.startsWith("external-import:") && Number.isSafeInteger(sourceBlock.endTurn) && sourceBlock.endTurn >= 0;
|
|
1485
|
+
if (reliableSource) event.formedTurn = sourceBlock.endTurn;
|
|
1486
|
+
} else if (!Number.isSafeInteger(event.formedTurn) || event.formedTurn < 0) {
|
|
1487
|
+
throw new TypeError("Invalid StrataGate snapshot: Event formedTurn must be a non-negative integer");
|
|
1488
|
+
}
|
|
1472
1489
|
}
|
|
1473
1490
|
for (const block of snapshot.blocks) {
|
|
1474
1491
|
if (block.processingStatus !== "pending" && block.processingStatus !== "ready") {
|
|
@@ -1715,6 +1732,7 @@ CREATE TABLE IF NOT EXISTS events (
|
|
|
1715
1732
|
tags_json TEXT NOT NULL,
|
|
1716
1733
|
quotes_json TEXT NOT NULL,
|
|
1717
1734
|
source_block_id TEXT NOT NULL,
|
|
1735
|
+
formed_turn INTEGER,
|
|
1718
1736
|
temporal_json TEXT NOT NULL,
|
|
1719
1737
|
scope TEXT NOT NULL,
|
|
1720
1738
|
criticality TEXT NOT NULL,
|
|
@@ -2020,6 +2038,7 @@ var SqliteStorage = class {
|
|
|
2020
2038
|
quotes: parseJson(row.quotes_json, "events.quotes_json"),
|
|
2021
2039
|
sourceMessageIds: sourcesByEvent.get(row.id) ?? [],
|
|
2022
2040
|
sourceBlockId: row.source_block_id,
|
|
2041
|
+
...row.formed_turn === null ? {} : { formedTurn: row.formed_turn },
|
|
2023
2042
|
temporal: (() => {
|
|
2024
2043
|
const temporal = parseJson(row.temporal_json, "events.temporal_json");
|
|
2025
2044
|
return { ...temporal, eventType: normalizeStandardEventType(temporal.eventType) };
|
|
@@ -2192,8 +2211,7 @@ var SqliteStorage = class {
|
|
|
2192
2211
|
externalMemoryImportJobs,
|
|
2193
2212
|
successfulModelResponses
|
|
2194
2213
|
};
|
|
2195
|
-
|
|
2196
|
-
return { snapshot: cloneSnapshot(snapshot), revision: space.revision };
|
|
2214
|
+
return { snapshot: cloneSnapshot(normalizeSnapshot(snapshot)), revision: space.revision };
|
|
2197
2215
|
}
|
|
2198
2216
|
async save(namespace, snapshot, expectedRevision) {
|
|
2199
2217
|
this.assertOpen();
|
|
@@ -2331,10 +2349,10 @@ var SqliteStorage = class {
|
|
|
2331
2349
|
const insertEvent = this.database.prepare(`
|
|
2332
2350
|
INSERT INTO events (
|
|
2333
2351
|
namespace, id, position, title, summary, narrative, tags_json, quotes_json, source_block_id,
|
|
2334
|
-
temporal_json, scope, criticality, confidence, status, superseded_by,
|
|
2352
|
+
formed_turn, temporal_json, scope, criticality, confidence, status, superseded_by,
|
|
2335
2353
|
mention_count, last_adopted_turn, last_retrieved_at, pinned, floor_weight, forced_cap,
|
|
2336
2354
|
created_at, updated_at
|
|
2337
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2355
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2338
2356
|
ON CONFLICT (namespace, id) DO UPDATE SET
|
|
2339
2357
|
position = excluded.position,
|
|
2340
2358
|
title = excluded.title,
|
|
@@ -2343,6 +2361,7 @@ var SqliteStorage = class {
|
|
|
2343
2361
|
tags_json = excluded.tags_json,
|
|
2344
2362
|
quotes_json = excluded.quotes_json,
|
|
2345
2363
|
source_block_id = excluded.source_block_id,
|
|
2364
|
+
formed_turn = excluded.formed_turn,
|
|
2346
2365
|
temporal_json = excluded.temporal_json,
|
|
2347
2366
|
scope = excluded.scope,
|
|
2348
2367
|
criticality = excluded.criticality,
|
|
@@ -2373,6 +2392,7 @@ var SqliteStorage = class {
|
|
|
2373
2392
|
JSON.stringify(event.tags),
|
|
2374
2393
|
JSON.stringify(event.quotes),
|
|
2375
2394
|
event.sourceBlockId,
|
|
2395
|
+
event.formedTurn ?? null,
|
|
2376
2396
|
JSON.stringify(event.temporal),
|
|
2377
2397
|
event.scope,
|
|
2378
2398
|
event.criticality,
|
|
@@ -2641,6 +2661,23 @@ var SqliteStorage = class {
|
|
|
2641
2661
|
if (!blockColumns.some(({ name: name2 }) => name2 === "processing_status")) {
|
|
2642
2662
|
this.database.exec("ALTER TABLE blocks ADD COLUMN processing_status TEXT NOT NULL DEFAULT 'ready' CHECK (processing_status IN ('pending', 'ready'))");
|
|
2643
2663
|
}
|
|
2664
|
+
const eventColumns = this.database.prepare("PRAGMA table_info('events')").all();
|
|
2665
|
+
if (!eventColumns.some(({ name: name2 }) => name2 === "formed_turn")) {
|
|
2666
|
+
this.database.exec("ALTER TABLE events ADD COLUMN formed_turn INTEGER");
|
|
2667
|
+
}
|
|
2668
|
+
this.database.exec(`
|
|
2669
|
+
UPDATE events
|
|
2670
|
+
SET formed_turn = (
|
|
2671
|
+
SELECT blocks.end_turn FROM blocks
|
|
2672
|
+
WHERE blocks.namespace = events.namespace AND blocks.id = events.source_block_id
|
|
2673
|
+
)
|
|
2674
|
+
WHERE formed_turn IS NULL AND EXISTS (
|
|
2675
|
+
SELECT 1 FROM blocks
|
|
2676
|
+
WHERE blocks.namespace = events.namespace
|
|
2677
|
+
AND blocks.id = events.source_block_id
|
|
2678
|
+
AND (blocks.thread_id IS NULL OR blocks.thread_id NOT LIKE 'external-import:%')
|
|
2679
|
+
)
|
|
2680
|
+
`);
|
|
2644
2681
|
const extractionColumns = this.database.prepare("PRAGMA table_info('extraction_jobs')").all();
|
|
2645
2682
|
if (!extractionColumns.some(({ name: name2 }) => name2 === "next_retry_at")) {
|
|
2646
2683
|
this.database.exec("ALTER TABLE extraction_jobs ADD COLUMN next_retry_at TEXT");
|
|
@@ -2734,7 +2771,6 @@ var EXTERNAL_MEMORY_AUTO_APPLY_CONFIDENCE = 0.85;
|
|
|
2734
2771
|
function externalMemoryFingerprint(value) {
|
|
2735
2772
|
return `${normalizeSearchText(value.title)}\0${normalizeSearchText(value.summary)}`;
|
|
2736
2773
|
}
|
|
2737
|
-
var DERIVATION_MAX_ATTEMPTS = 3;
|
|
2738
2774
|
var DERIVATION_BACKOFF_MS = 1e3;
|
|
2739
2775
|
var StrataGate = class _StrataGate {
|
|
2740
2776
|
blockTurnSizeValue;
|
|
@@ -2919,6 +2955,7 @@ var StrataGate = class _StrataGate {
|
|
|
2919
2955
|
...job,
|
|
2920
2956
|
status: "failed",
|
|
2921
2957
|
lastError: "Graph projection was interrupted before completion.",
|
|
2958
|
+
nextRetryAt: memory.retryAt(job.attempts),
|
|
2922
2959
|
updatedAt: now
|
|
2923
2960
|
});
|
|
2924
2961
|
}
|
|
@@ -3077,6 +3114,7 @@ var StrataGate = class _StrataGate {
|
|
|
3077
3114
|
job.status = "pending";
|
|
3078
3115
|
job.attempts = 0;
|
|
3079
3116
|
job.lastError = null;
|
|
3117
|
+
job.nextRetryAt = null;
|
|
3080
3118
|
job.updatedAt = toUtc8Iso(this.now());
|
|
3081
3119
|
});
|
|
3082
3120
|
const batch = await this.claimGraphProjection(jobId);
|
|
@@ -3675,7 +3713,7 @@ var StrataGate = class _StrataGate {
|
|
|
3675
3713
|
}
|
|
3676
3714
|
async claimNextElementProjection() {
|
|
3677
3715
|
return this.commitMutation(() => {
|
|
3678
|
-
const job = [...this.elementProjectionJobs.values()].
|
|
3716
|
+
const job = [...this.elementProjectionJobs.values()].filter((candidate) => candidate.attempts < DERIVATION_MAX_ATTEMPTS && (candidate.status === "pending" || candidate.status === "failed")).sort((left, right) => Number(left.status !== "pending") - Number(right.status !== "pending") || left.createdAt.localeCompare(right.createdAt))[0];
|
|
3679
3717
|
if (!job) return null;
|
|
3680
3718
|
const events = job.sourceEventIds.flatMap((id) => this.events.find((event) => event.id === id) ?? []);
|
|
3681
3719
|
if (events.length === 0) {
|
|
@@ -3729,7 +3767,8 @@ var StrataGate = class _StrataGate {
|
|
|
3729
3767
|
}
|
|
3730
3768
|
async claimGraphProjection(jobId) {
|
|
3731
3769
|
return this.commitMutation(() => {
|
|
3732
|
-
const
|
|
3770
|
+
const now = this.now().getTime();
|
|
3771
|
+
const job = [...this.graphProjectionJobs.values()].filter((candidate) => (jobId === void 0 || candidate.id === jobId) && candidate.attempts < DERIVATION_MAX_ATTEMPTS && (candidate.status === "pending" || candidate.status === "failed" && candidate.nextRetryAt !== null && Date.parse(candidate.nextRetryAt) <= now)).sort((left, right) => Number(left.status !== "pending") - Number(right.status !== "pending") || right.priority - left.priority || left.createdAt.localeCompare(right.createdAt))[0];
|
|
3733
3772
|
if (!job) return null;
|
|
3734
3773
|
const events = job.sourceEventIds.flatMap((id) => this.events.find((event) => event.id === id) ?? []);
|
|
3735
3774
|
if (events.length === 0) throw new Error(`Graph projection ${job.id} has no available source events`);
|
|
@@ -3744,14 +3783,14 @@ var StrataGate = class _StrataGate {
|
|
|
3744
3783
|
(event.temporal.participants ?? []).join(" ")
|
|
3745
3784
|
].join(" ")).join(" "));
|
|
3746
3785
|
const relevantNodes = this.graphNodes.filter((node) => [node.name, ...node.aliases].some((name2) => eventText.includes(normalizeSearchText(name2)))).concat([...this.graphNodes].sort((left, right) => right.updatedAt.localeCompare(left.updatedAt)).slice(0, 24));
|
|
3747
|
-
const existingNodes = [...new Map(relevantNodes.map((node) => [node.id, node])).values()].slice(0,
|
|
3786
|
+
const existingNodes = [...new Map(relevantNodes.map((node) => [node.id, node])).values()].slice(0, 32);
|
|
3748
3787
|
const nodeIds = new Set(existingNodes.map(({ id }) => id));
|
|
3749
3788
|
return {
|
|
3750
3789
|
jobId: job.id,
|
|
3751
3790
|
projectorVersion: job.projectorVersion,
|
|
3752
3791
|
events: structuredClone(events),
|
|
3753
3792
|
existingNodes: structuredClone(existingNodes),
|
|
3754
|
-
existingEdges: structuredClone(this.graphEdges.filter(({ fromNodeId, toNodeId }) => nodeIds.has(fromNodeId) && nodeIds.has(toNodeId)).slice(-
|
|
3793
|
+
existingEdges: structuredClone(this.graphEdges.filter(({ fromNodeId, toNodeId }) => nodeIds.has(fromNodeId) && nodeIds.has(toNodeId)).slice(-60))
|
|
3755
3794
|
};
|
|
3756
3795
|
});
|
|
3757
3796
|
}
|
|
@@ -3777,6 +3816,7 @@ var StrataGate = class _StrataGate {
|
|
|
3777
3816
|
job.edgeIds = touched.edgeIds;
|
|
3778
3817
|
job.reason = typeof result.reason === "string" ? result.reason.trim().replace(/\s+/g, " ").slice(0, 500) || null : null;
|
|
3779
3818
|
job.lastError = null;
|
|
3819
|
+
job.nextRetryAt = null;
|
|
3780
3820
|
job.updatedAt = toUtc8Iso(this.now());
|
|
3781
3821
|
return touched;
|
|
3782
3822
|
});
|
|
@@ -3787,6 +3827,7 @@ var StrataGate = class _StrataGate {
|
|
|
3787
3827
|
if (job.status === "completed") return;
|
|
3788
3828
|
job.status = "failed";
|
|
3789
3829
|
job.lastError = errorMessage(error);
|
|
3830
|
+
job.nextRetryAt = this.retryAt(job.attempts);
|
|
3790
3831
|
job.updatedAt = toUtc8Iso(this.now());
|
|
3791
3832
|
});
|
|
3792
3833
|
}
|
|
@@ -4052,8 +4093,10 @@ var StrataGate = class _StrataGate {
|
|
|
4052
4093
|
const sourceMessageIds = requestedRefs.length > 0 ? requestedRefs : sourceBlock.l5Raw.map((message) => message.id);
|
|
4053
4094
|
const now = toUtc8Iso(this.now());
|
|
4054
4095
|
const criticality = input.criticality ?? "routine";
|
|
4096
|
+
const formedTurn = sourceBlock.threadId?.startsWith("external-import:") ? this.currentTurn : sourceBlock.endTurn;
|
|
4055
4097
|
const event = {
|
|
4056
4098
|
id: input.id ?? this.idFactory("evt"),
|
|
4099
|
+
formedTurn,
|
|
4057
4100
|
title: input.title.trim(),
|
|
4058
4101
|
summary: input.summary.trim(),
|
|
4059
4102
|
narrative: input.narrative?.trim() || input.summary.trim(),
|
|
@@ -4072,7 +4115,7 @@ var StrataGate = class _StrataGate {
|
|
|
4072
4115
|
supersededBy: null,
|
|
4073
4116
|
weight: {
|
|
4074
4117
|
mentionCount: 1,
|
|
4075
|
-
lastAdoptedTurn:
|
|
4118
|
+
lastAdoptedTurn: formedTurn,
|
|
4076
4119
|
lastRetrievedAt: null,
|
|
4077
4120
|
pinned: false,
|
|
4078
4121
|
floorWeight: criticalityFloor(criticality),
|
|
@@ -4169,6 +4212,7 @@ var StrataGate = class _StrataGate {
|
|
|
4169
4212
|
edgeIds: [],
|
|
4170
4213
|
reason: null,
|
|
4171
4214
|
lastError: null,
|
|
4215
|
+
nextRetryAt: null,
|
|
4172
4216
|
createdAt: now,
|
|
4173
4217
|
updatedAt: now
|
|
4174
4218
|
};
|
|
@@ -4991,6 +5035,48 @@ function renderBlocksForDiagnostics(blocks, finish) {
|
|
|
4991
5035
|
const rendered = blocks.map(renderBlockForDiagnostics).join("\n\n");
|
|
4992
5036
|
return rendered || `[no model blocks; finish=${finish}]`;
|
|
4993
5037
|
}
|
|
5038
|
+
function compactGraphProjectionContext(context) {
|
|
5039
|
+
const compactValue = (value) => Array.isArray(value) ? value.slice(0, 12).map((entry) => entry.slice(0, 160)) : value.slice(0, 400);
|
|
5040
|
+
return {
|
|
5041
|
+
jobId: context.jobId,
|
|
5042
|
+
projectorVersion: context.projectorVersion,
|
|
5043
|
+
events: context.events.map((event) => ({
|
|
5044
|
+
id: event.id,
|
|
5045
|
+
title: event.title,
|
|
5046
|
+
summary: event.summary,
|
|
5047
|
+
narrative: event.narrative,
|
|
5048
|
+
tags: event.tags,
|
|
5049
|
+
quotes: event.quotes,
|
|
5050
|
+
temporal: event.temporal,
|
|
5051
|
+
scope: event.scope,
|
|
5052
|
+
criticality: event.criticality,
|
|
5053
|
+
status: event.status
|
|
5054
|
+
})),
|
|
5055
|
+
existingNodes: context.existingNodes.slice(0, 32).map((node) => ({
|
|
5056
|
+
id: node.id,
|
|
5057
|
+
name: node.name,
|
|
5058
|
+
type: node.type,
|
|
5059
|
+
aliases: node.aliases.slice(0, 12),
|
|
5060
|
+
tags: node.tags?.slice(0, 12),
|
|
5061
|
+
currentState: node.currentState.slice(0, 600),
|
|
5062
|
+
facts: node.facts.filter(({ status }) => status === "active" || status === "disputed").slice(-12).map((fact) => ({
|
|
5063
|
+
key: fact.key,
|
|
5064
|
+
value: compactValue(fact.value),
|
|
5065
|
+
status: fact.status,
|
|
5066
|
+
sourceEventIds: fact.sourceEventIds.slice(-16)
|
|
5067
|
+
})),
|
|
5068
|
+
status: node.status,
|
|
5069
|
+
sourceEventIds: node.sourceEventIds.slice(-16)
|
|
5070
|
+
})),
|
|
5071
|
+
existingEdges: context.existingEdges.slice(-60).map((edge) => ({
|
|
5072
|
+
fromNodeId: edge.fromNodeId,
|
|
5073
|
+
toNodeId: edge.toNodeId,
|
|
5074
|
+
relation: edge.relation,
|
|
5075
|
+
status: edge.status,
|
|
5076
|
+
sourceEventIds: edge.sourceEventIds.slice(-16)
|
|
5077
|
+
}))
|
|
5078
|
+
};
|
|
5079
|
+
}
|
|
4994
5080
|
var DshModelBridge = class {
|
|
4995
5081
|
constructor(ctx, config) {
|
|
4996
5082
|
this.ctx = ctx;
|
|
@@ -5104,8 +5190,8 @@ var DshModelBridge = class {
|
|
|
5104
5190
|
const eventIds = new Set(context.events.map((event) => event.id));
|
|
5105
5191
|
const raw = object(await this.callStructured(
|
|
5106
5192
|
"graphProjector",
|
|
5107
|
-
`Project the supplied Events into the current Knowledge Graph, then call ${STRUCTURED_TOOLS.graphProjector.name} exactly once. Events are the sole source of truth; never use legacy Element data. Return stable entity nodes for people, projects, organizations, tools, and places. Use aliases to merge spelling/case/separator variants. Give every returned node 1-6 concise semantic role tags such as benchmark, evaluation, memory-plugin, parser, or development-tool; tags describe the node's specific role and never replace its person/project/organization/tool/place type. Reuse stable tag wording when possible. Put attributes in node facts and every relationship in a directed edge using fromRef/toRef\u2014never encode a relationship as a fact string. Prefer concise canonical Chinese relation labels such as \u4F7F\u7528\u3001\u5C5E\u4E8E\u3001\u521B\u5EFA\u3001\u53C2\u4E0E\u3001\u8D21\u732E\u3001\u4F9D\u8D56\u3001\u4F4D\u4E8E\u3001\u76F8\u5173. Every node, fact, and edge must cite only supplied Event ids. Do not return text.`,
|
|
5108
|
-
context
|
|
5193
|
+
`Project the supplied Events into the current Knowledge Graph, then call ${STRUCTURED_TOOLS.graphProjector.name} exactly once. Events are the sole source of truth; never use legacy Element data. Return only nodes and edges touched by the supplied Events; never echo unchanged historical graph records. Return at most 24 nodes and 32 edges. Use stable entity nodes for people, projects, organizations, tools, and places. Use aliases to merge spelling/case/separator variants. Give every returned node 1-6 concise semantic role tags such as benchmark, evaluation, memory-plugin, parser, or development-tool; tags describe the node's specific role and never replace its person/project/organization/tool/place type. Reuse stable tag wording when possible. Put attributes in node facts and every relationship in a directed edge using fromRef/toRef\u2014never encode a relationship as a fact string. Prefer concise canonical Chinese relation labels such as \u4F7F\u7528\u3001\u5C5E\u4E8E\u3001\u521B\u5EFA\u3001\u53C2\u4E0E\u3001\u8D21\u732E\u3001\u4F9D\u8D56\u3001\u4F4D\u4E8E\u3001\u76F8\u5173. Every node, fact, and edge must cite only supplied Event ids. Do not return text.`,
|
|
5194
|
+
compactGraphProjectionContext(context)
|
|
5109
5195
|
));
|
|
5110
5196
|
const nodes = (Array.isArray(raw.nodes) ? raw.nodes : []).flatMap((candidate) => {
|
|
5111
5197
|
const item = object(candidate);
|
|
@@ -5134,7 +5220,7 @@ var DshModelBridge = class {
|
|
|
5134
5220
|
...typeof item.confidence === "number" ? { confidence: item.confidence } : {},
|
|
5135
5221
|
sourceEventIds
|
|
5136
5222
|
}];
|
|
5137
|
-
});
|
|
5223
|
+
}).slice(0, 24);
|
|
5138
5224
|
const refs = new Set(nodes.map(({ ref }) => ref));
|
|
5139
5225
|
const edges = (Array.isArray(raw.edges) ? raw.edges : []).flatMap((candidate) => {
|
|
5140
5226
|
const item = object(candidate);
|
|
@@ -5153,7 +5239,7 @@ var DshModelBridge = class {
|
|
|
5153
5239
|
...typeof item.confidence === "number" ? { confidence: item.confidence } : {},
|
|
5154
5240
|
sourceEventIds
|
|
5155
5241
|
}];
|
|
5156
|
-
});
|
|
5242
|
+
}).slice(0, 32);
|
|
5157
5243
|
return { reason: text2(raw.reason, "Projected Event evidence into the Knowledge Graph."), nodes, edges };
|
|
5158
5244
|
};
|
|
5159
5245
|
externalMemoryDecider = async (context) => {
|
|
@@ -5197,7 +5283,9 @@ var DshModelBridge = class {
|
|
|
5197
5283
|
let useOff = await this.shouldUseOff(baseRoute);
|
|
5198
5284
|
let lastError;
|
|
5199
5285
|
let lastResponse = "";
|
|
5286
|
+
let attemptsUsed = 0;
|
|
5200
5287
|
for (let attempt = 1; attempt <= JSON_RESPONSE_ATTEMPTS; attempt += 1) {
|
|
5288
|
+
attemptsUsed = attempt;
|
|
5201
5289
|
const message = createUserMessage({
|
|
5202
5290
|
content: [{ type: "text", text: JSON.stringify(payload) }],
|
|
5203
5291
|
source: { kind: "plugin", plugin: "stratagate-memory" }
|
|
@@ -5306,13 +5394,14 @@ ${JSON_RETRY_INSTRUCTION}`,
|
|
|
5306
5394
|
`StrataGate ${STRUCTURED_TOOLS[kind].name} call was truncated before valid arguments`,
|
|
5307
5395
|
{ cause: error, response: responseForError }
|
|
5308
5396
|
) : error;
|
|
5397
|
+
if (kind === "graphProjector" && finish.kind === "max-tokens") break;
|
|
5309
5398
|
if (attempt < JSON_RESPONSE_ATTEMPTS) {
|
|
5310
5399
|
this.ctx.logger.warn(`stratagate-memory model returned an invalid structured tool call; retrying (${attempt}/${JSON_RESPONSE_ATTEMPTS})`);
|
|
5311
5400
|
}
|
|
5312
5401
|
}
|
|
5313
5402
|
}
|
|
5314
5403
|
throw new ModelJsonResponseError(
|
|
5315
|
-
`StrataGate model did not produce a valid ${STRUCTURED_TOOLS[kind].name} call after ${
|
|
5404
|
+
`StrataGate model did not produce a valid ${STRUCTURED_TOOLS[kind].name} call after ${attemptsUsed} attempt${attemptsUsed === 1 ? "" : "s"}`,
|
|
5316
5405
|
{ cause: lastError, response: lastResponse }
|
|
5317
5406
|
);
|
|
5318
5407
|
}
|
|
@@ -5715,6 +5804,9 @@ var DRAIN_BASE_BACKOFF_MS = 2e3;
|
|
|
5715
5804
|
var DRAIN_MAX_BACKOFF_MS = 6e4;
|
|
5716
5805
|
var BACKGROUND_WORKER_INITIAL_DELAY_MS = 250;
|
|
5717
5806
|
var BACKGROUND_WORKER_INTERVAL_MS = 3e3;
|
|
5807
|
+
function graphProjectionCanRun(job, now = Date.now()) {
|
|
5808
|
+
return job.attempts < DERIVATION_MAX_ATTEMPTS && (job.status === "pending" || job.status === "failed" && job.nextRetryAt != null && Date.parse(job.nextRetryAt) <= now);
|
|
5809
|
+
}
|
|
5718
5810
|
var AUTO_EVENT_LIMIT = 4;
|
|
5719
5811
|
var AUTO_ELEMENT_LIMIT = 4;
|
|
5720
5812
|
var AUTO_MEMORY_TOKEN_BUDGET = 900;
|
|
@@ -5849,7 +5941,7 @@ var StrataGateRuntime = class {
|
|
|
5849
5941
|
const runnable = [
|
|
5850
5942
|
...memory.listSummaryJobs(),
|
|
5851
5943
|
...memory.listExtractionJobs()
|
|
5852
|
-
].some((job) => job.status === "pending" || job.status === "failed" && job.nextRetryAt !== null && Date.parse(job.nextRetryAt) <= Date.now()) || memory.listGraphProjectionJobs().some((
|
|
5944
|
+
].some((job) => job.status === "pending" || job.status === "failed" && job.nextRetryAt !== null && Date.parse(job.nextRetryAt) <= Date.now()) || memory.listGraphProjectionJobs().some((job) => graphProjectionCanRun(job));
|
|
5853
5945
|
if (!runnable) return;
|
|
5854
5946
|
const hasActiveSessionWork = [
|
|
5855
5947
|
...this.derivationTimers.keys(),
|
|
@@ -7127,7 +7219,7 @@ var StrataGateRuntime = class {
|
|
|
7127
7219
|
const namespace = this.namespaceFor(session);
|
|
7128
7220
|
if (this.closed || this.migrationTimers.has(namespace)) return;
|
|
7129
7221
|
if (typeof memory.listGraphProjectionJobs !== "function") return;
|
|
7130
|
-
const pending = memory.listGraphProjectionJobs().some((
|
|
7222
|
+
const pending = memory.listGraphProjectionJobs().some((job) => graphProjectionCanRun(job));
|
|
7131
7223
|
if (!pending) return;
|
|
7132
7224
|
const timer = setTimeout(() => {
|
|
7133
7225
|
this.migrationTimers.delete(namespace);
|
|
@@ -7833,6 +7925,10 @@ function currentPluginVersion() {
|
|
|
7833
7925
|
return "unknown";
|
|
7834
7926
|
}
|
|
7835
7927
|
var STRATAGATE_DSH_VERSION = currentPluginVersion();
|
|
7928
|
+
function graphProjectionIsProcessing(job) {
|
|
7929
|
+
if (job.status === "running") return true;
|
|
7930
|
+
return job.attempts < DERIVATION_MAX_ATTEMPTS && (job.status === "pending" || job.status === "failed" && job.nextRetryAt !== null);
|
|
7931
|
+
}
|
|
7836
7932
|
function installedPackageVersion(names) {
|
|
7837
7933
|
for (const name2 of names) {
|
|
7838
7934
|
try {
|
|
@@ -7923,7 +8019,8 @@ function appendWeightSegment(points, event, fromTurn, toTurn, mentionCount) {
|
|
|
7923
8019
|
if (toTurn < fromTurn) return;
|
|
7924
8020
|
if (toTurn === fromTurn) return;
|
|
7925
8021
|
const span = toTurn - fromTurn;
|
|
7926
|
-
const
|
|
8022
|
+
const samples = Math.min(256, Math.max(12, Math.ceil(span * 12)));
|
|
8023
|
+
const step = span / samples;
|
|
7927
8024
|
for (let turn = fromTurn; turn < toTurn; turn += step) {
|
|
7928
8025
|
points.push({ turn, weight: sampledEventWeight(event, turn, fromTurn, mentionCount), kind: "sample" });
|
|
7929
8026
|
}
|
|
@@ -7931,65 +8028,116 @@ function appendWeightSegment(points, event, fromTurn, toTurn, mentionCount) {
|
|
|
7931
8028
|
}
|
|
7932
8029
|
function eventWeightTrajectory(snapshot, event) {
|
|
7933
8030
|
const currentTurn = snapshot.currentTurn;
|
|
8031
|
+
const formedTurn = Number.isSafeInteger(event.formedTurn) && event.formedTurn >= 0 ? event.formedTurn : null;
|
|
8032
|
+
const sourceBlock = snapshot.blocks.find(({ id }) => id === event.sourceBlockId);
|
|
8033
|
+
const sourceBlockEndTurn = Number.isSafeInteger(sourceBlock?.endTurn) && sourceBlock.endTurn >= 0 ? sourceBlock.endTurn : null;
|
|
7934
8034
|
const effectiveAdoptions = Math.max(0, event.weight.mentionCount - 1);
|
|
7935
8035
|
const adoptionReceipts = snapshot.usageReceipts.filter(({ eventIds }) => eventIds.includes(event.id));
|
|
7936
8036
|
const adoptionTurns = adoptionReceipts.map(({ audit: audit2 }) => audit2?.turn).filter((turn) => Number.isSafeInteger(turn) && turn >= 0).sort((left, right) => left - right);
|
|
7937
|
-
const
|
|
8037
|
+
const confirmedAdoptionTurns = [...adoptionTurns];
|
|
8038
|
+
if (effectiveAdoptions > 0 && Number.isSafeInteger(event.weight.lastAdoptedTurn) && event.weight.lastAdoptedTurn >= 0) {
|
|
8039
|
+
confirmedAdoptionTurns.push(event.weight.lastAdoptedTurn);
|
|
8040
|
+
}
|
|
8041
|
+
confirmedAdoptionTurns.sort((left, right) => left - right);
|
|
8042
|
+
const groupedAdoptions = [...new Set(confirmedAdoptionTurns)].map((turn) => ({
|
|
8043
|
+
turn,
|
|
8044
|
+
adoptionCount: Math.max(1, adoptionTurns.filter((value) => value === turn).length)
|
|
8045
|
+
}));
|
|
8046
|
+
const earliestKnownAdoptionTurn = groupedAdoptions[0]?.turn ?? null;
|
|
8047
|
+
const trajectoryStartTurn = formedTurn ?? sourceBlockEndTurn ?? earliestKnownAdoptionTurn ?? currentTurn;
|
|
8048
|
+
const formationTurnSource = formedTurn !== null ? "formedTurn" : sourceBlockEndTurn !== null ? "sourceBlock" : null;
|
|
8049
|
+
const historyComplete = adoptionReceipts.length === effectiveAdoptions && adoptionTurns.length === adoptionReceipts.length && (effectiveAdoptions === 0 || adoptionTurns.at(-1) === event.weight.lastAdoptedTurn) && adoptionTurns.every((turn) => turn >= trajectoryStartTurn) && (effectiveAdoptions > 0 || event.weight.lastAdoptedTurn === trajectoryStartTurn);
|
|
8050
|
+
const adoptionHistoryComplete = adoptionReceipts.length === effectiveAdoptions && adoptionReceipts.every((receipt) => Boolean(receipt.createdAt) && Number.isFinite(Date.parse(receipt.createdAt)) && Boolean(receipt.audit?.sessionId?.trim()) && Number.isSafeInteger(receipt.audit?.turn) && receipt.audit.turn >= 0) && (formedTurn === null || adoptionReceipts.every((receipt) => receipt.audit.turn >= formedTurn));
|
|
8051
|
+
const adoptionHistory = adoptionReceipts.filter((receipt) => Boolean(receipt.createdAt) && Number.isFinite(Date.parse(receipt.createdAt)) && Boolean(receipt.audit?.sessionId?.trim()) && Number.isSafeInteger(receipt.audit?.turn) && receipt.audit.turn >= 0 && (formedTurn === null || receipt.audit.turn >= formedTurn)).map((receipt) => ({
|
|
8052
|
+
receiptId: receipt.id,
|
|
8053
|
+
createdAt: receipt.createdAt,
|
|
8054
|
+
sessionId: receipt.audit.sessionId,
|
|
8055
|
+
turn: receipt.audit.turn,
|
|
8056
|
+
...formedTurn === null ? {} : { relativeTurn: receipt.audit.turn - formedTurn },
|
|
8057
|
+
evidenceRefs: receipt.audit?.evidenceRefs ?? []
|
|
8058
|
+
})).sort((left, right) => left.turn - right.turn || left.createdAt.localeCompare(right.createdAt));
|
|
7938
8059
|
const canInterpolate = event.status !== "forgotten" && event.status !== "archived" && event.weight.forcedCap === null && !event.weight.pinned;
|
|
7939
|
-
const
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
|
|
7943
|
-
|
|
7944
|
-
|
|
7945
|
-
}
|
|
7946
|
-
|
|
7947
|
-
|
|
7948
|
-
|
|
7949
|
-
points.push({ turn: anchorTurn, weight: 1, kind: "adoption", label: "\u91C7\u7528" });
|
|
7950
|
-
for (const [index, turn] of adoptionTurns.slice(1).entries()) {
|
|
7951
|
-
appendWeightSegment(points, event, anchorTurn, turn, mentionCount);
|
|
7952
|
-
points.push({ turn, weight: 1, kind: "adoption", label: index === adoptionTurns.length - 2 ? "\u518D\u6B21\u91C7\u7528" : "\u91C7\u7528" });
|
|
8060
|
+
const segments = [];
|
|
8061
|
+
const originPoint = formationTurnSource ? { turn: trajectoryStartTurn, weight: 1, kind: "creation", label: formationTurnSource === "formedTurn" ? "\u5F62\u6210" : "\u6765\u6E90" } : null;
|
|
8062
|
+
if (canInterpolate && historyComplete && originPoint) {
|
|
8063
|
+
const lifecycle = [originPoint];
|
|
8064
|
+
let anchorTurn = trajectoryStartTurn;
|
|
8065
|
+
let mentionCount = 1;
|
|
8066
|
+
for (const { turn, adoptionCount } of groupedAdoptions) {
|
|
8067
|
+
if (turn < trajectoryStartTurn || turn > currentTurn) continue;
|
|
8068
|
+
appendWeightSegment(lifecycle, event, anchorTurn, turn, mentionCount);
|
|
8069
|
+
lifecycle.push({ turn, weight: 1, kind: "adoption", adoptionCount, label: adoptionCount > 1 ? `\u91C7\u7EB3 \xD7${adoptionCount}` : "\u91C7\u7EB3" });
|
|
7953
8070
|
anchorTurn = turn;
|
|
7954
|
-
mentionCount +=
|
|
8071
|
+
mentionCount += adoptionCount;
|
|
7955
8072
|
}
|
|
7956
|
-
appendWeightSegment(
|
|
8073
|
+
appendWeightSegment(lifecycle, event, anchorTurn, currentTurn, mentionCount);
|
|
8074
|
+
segments.push({ certainty: "known", points: lifecycle });
|
|
7957
8075
|
} else if (canInterpolate) {
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
8076
|
+
let anchorPoint = originPoint;
|
|
8077
|
+
let mentionCount = 1;
|
|
8078
|
+
const visibleAdoptions = groupedAdoptions.filter(({ turn }) => turn >= trajectoryStartTurn && turn <= currentTurn);
|
|
8079
|
+
for (const { turn, adoptionCount } of visibleAdoptions) {
|
|
8080
|
+
if (anchorPoint && turn > anchorPoint.turn) {
|
|
8081
|
+
const incomplete = [anchorPoint];
|
|
8082
|
+
appendWeightSegment(incomplete, event, anchorPoint.turn, turn, mentionCount);
|
|
8083
|
+
incomplete.push({ turn, weight: 1, kind: "adoption", adoptionCount, label: adoptionCount > 1 ? `\u91C7\u7EB3 \xD7${adoptionCount}` : "\u91C7\u7EB3" });
|
|
8084
|
+
segments.push({ certainty: "incomplete", points: incomplete });
|
|
8085
|
+
} else {
|
|
8086
|
+
segments.push({ certainty: "known", points: [{ turn, weight: 1, kind: "adoption", adoptionCount, label: adoptionCount > 1 ? `\u91C7\u7EB3 \xD7${adoptionCount}` : "\u91C7\u7EB3" }] });
|
|
8087
|
+
}
|
|
8088
|
+
anchorPoint = { turn, weight: 1, kind: "adoption", adoptionCount, label: adoptionCount > 1 ? `\u91C7\u7EB3 \xD7${adoptionCount}` : "\u91C7\u7EB3" };
|
|
8089
|
+
mentionCount += adoptionCount;
|
|
8090
|
+
}
|
|
8091
|
+
if (anchorPoint && anchorPoint.turn <= currentTurn) {
|
|
8092
|
+
const latestIsReliable = effectiveAdoptions > 0 && anchorPoint.turn === event.weight.lastAdoptedTurn && visibleAdoptions.at(-1)?.turn === event.weight.lastAdoptedTurn;
|
|
8093
|
+
const tail = [anchorPoint];
|
|
8094
|
+
appendWeightSegment(tail, event, anchorPoint.turn, currentTurn, latestIsReliable ? event.weight.mentionCount : mentionCount);
|
|
8095
|
+
if (tail.length > 1) segments.push({ certainty: latestIsReliable ? "known" : "incomplete", points: tail });
|
|
8096
|
+
} else if (originPoint && originPoint.turn <= currentTurn) {
|
|
8097
|
+
const tail = [originPoint];
|
|
8098
|
+
appendWeightSegment(tail, event, originPoint.turn, currentTurn, 1);
|
|
8099
|
+
if (tail.length > 1) segments.push({ certainty: historyComplete ? "known" : "incomplete", points: tail });
|
|
8100
|
+
else segments.push({ certainty: "known", points: [originPoint] });
|
|
8101
|
+
}
|
|
8102
|
+
} else if (originPoint) {
|
|
8103
|
+
segments.push({ certainty: "known", points: [originPoint] });
|
|
7963
8104
|
}
|
|
7964
8105
|
const currentWeight = memoryWeightAt(event, currentTurn);
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
weight: currentWeight,
|
|
7971
|
-
label: `${points[points.length - 1].label} \xB7 \u5F53\u524D`
|
|
7972
|
-
};
|
|
8106
|
+
const lastSegment = segments.at(-1);
|
|
8107
|
+
if (!lastSegment || lastSegment.points.at(-1)?.turn !== currentTurn) {
|
|
8108
|
+
segments.push({ certainty: "known", points: [{ turn: currentTurn, weight: currentWeight, kind: "current", label: "\u5F53\u524D" }] });
|
|
8109
|
+
} else if (lastSegment.points.at(-1)?.kind === "sample") {
|
|
8110
|
+
lastSegment.points[lastSegment.points.length - 1] = { ...lastSegment.points[lastSegment.points.length - 1], weight: currentWeight, kind: "current", label: "\u5F53\u524D" };
|
|
7973
8111
|
} else {
|
|
7974
|
-
|
|
8112
|
+
segments.push({ certainty: "known", points: [{ turn: currentTurn, weight: currentWeight, kind: "current", label: "\u5F53\u524D" }] });
|
|
7975
8113
|
}
|
|
8114
|
+
const points = segments.flatMap(({ points: segmentPoints }) => segmentPoints);
|
|
7976
8115
|
return {
|
|
7977
8116
|
scale: "conversation_turn",
|
|
8117
|
+
formedTurn,
|
|
8118
|
+
trajectoryStartTurn,
|
|
8119
|
+
formationTurnSource,
|
|
7978
8120
|
currentTurn,
|
|
7979
8121
|
currentWeight,
|
|
7980
8122
|
effectiveAdoptions,
|
|
8123
|
+
floorWeight: event.weight.floorWeight,
|
|
8124
|
+
criticality: event.criticality,
|
|
7981
8125
|
latestAdoptionTurn: effectiveAdoptions > 0 ? event.weight.lastAdoptedTurn : null,
|
|
7982
8126
|
turnsSinceLatestAdoption: effectiveAdoptions > 0 ? Math.max(0, currentTurn - event.weight.lastAdoptedTurn) : null,
|
|
7983
8127
|
lastRetrievedAt: event.weight.lastRetrievedAt,
|
|
7984
8128
|
recordedAdoptionTurns: adoptionTurns,
|
|
7985
8129
|
historyComplete,
|
|
8130
|
+
adoptionHistoryComplete,
|
|
8131
|
+
adoptionHistory,
|
|
8132
|
+
segments,
|
|
7986
8133
|
points,
|
|
7987
|
-
note: !canInterpolate ? "\u56FA\u5B9A\u3001\u5C01\u5B58\u6216\u72B6\u6001\u4E0A\u9650\u7684\u53D8\u66F4\u8F6E\u6B21\u6CA1\u6709\u5386\u53F2\u8BB0\u5F55\uFF0C\u56E0\u6B64\u4EC5\u663E\u793A\u5F53\u524D\u771F\u5B9E\u6743\u91CD\u3002" :
|
|
8134
|
+
note: !canInterpolate ? "\u56FA\u5B9A\u3001\u5C01\u5B58\u6216\u72B6\u6001\u4E0A\u9650\u7684\u53D8\u66F4\u8F6E\u6B21\u6CA1\u6709\u5386\u53F2\u8BB0\u5F55\uFF0C\u56E0\u6B64\u4EC5\u663E\u793A\u5F53\u524D\u771F\u5B9E\u6743\u91CD\u3002" : !historyComplete ? "\u65E7\u7248\u672C\u672A\u8BB0\u5F55\u90E8\u5206\u91C7\u7EB3\u7684\u5177\u4F53\u8F6E\u6B21\uFF1B\u786E\u5B9A\u8282\u70B9\u4E0E\u533A\u95F4\u7167\u5E38\u663E\u793A\uFF0C\u7F3A\u5931\u533A\u95F4\u4EC5\u4F5C\u8D8B\u52BF\u8FDE\u63A5\u3002" : effectiveAdoptions > 0 ? "\u91C7\u7EB3\u8F6E\u6B21\u6765\u81EA\u771F\u5B9E\u4F7F\u7528\u56DE\u6267\u3002" : "\u5C1A\u672A\u88AB Agent \u91C7\u7EB3\u3002"
|
|
7988
8135
|
};
|
|
7989
8136
|
}
|
|
7990
8137
|
function eventSummary(event, snapshot) {
|
|
7991
8138
|
return {
|
|
7992
8139
|
id: event.id,
|
|
8140
|
+
formedTurn: event.formedTurn,
|
|
7993
8141
|
title: event.title,
|
|
7994
8142
|
summary: event.summary,
|
|
7995
8143
|
narrative: event.narrative,
|
|
@@ -8100,7 +8248,7 @@ async function overview(runtime, cachedEntries) {
|
|
|
8100
8248
|
kind: "graph-projection",
|
|
8101
8249
|
status: job.status,
|
|
8102
8250
|
attempts: job.attempts,
|
|
8103
|
-
nextRetryAt:
|
|
8251
|
+
nextRetryAt: job.nextRetryAt,
|
|
8104
8252
|
lastError: job.lastError?.slice(0, 500) ?? null,
|
|
8105
8253
|
lastErrorFull: job.lastError,
|
|
8106
8254
|
updatedAt: job.updatedAt,
|
|
@@ -8112,7 +8260,7 @@ async function overview(runtime, cachedEntries) {
|
|
|
8112
8260
|
};
|
|
8113
8261
|
};
|
|
8114
8262
|
const failedJobs = snapshot.summaryJobs.filter(({ status }) => status === "failed").length + snapshot.extractionJobs.filter(({ status }) => status === "failed").length + snapshot.graphProjectionJobs.filter(({ status }) => status === "failed").length;
|
|
8115
|
-
const processingJobs = snapshot.summaryJobs.filter(({ status, nextRetryAt }) => status === "pending" || status === "running" || status === "failed" && nextRetryAt !== null).length + snapshot.extractionJobs.filter(({ status, nextRetryAt }) => status === "running" || status === "failed" && nextRetryAt !== null).length + snapshot.graphProjectionJobs.filter(
|
|
8263
|
+
const processingJobs = snapshot.summaryJobs.filter(({ status, nextRetryAt }) => status === "pending" || status === "running" || status === "failed" && nextRetryAt !== null).length + snapshot.extractionJobs.filter(({ status, nextRetryAt }) => status === "running" || status === "failed" && nextRetryAt !== null).length + snapshot.graphProjectionJobs.filter(graphProjectionIsProcessing).length;
|
|
8116
8264
|
const failedJobDetails = [
|
|
8117
8265
|
...snapshot.summaryJobs.filter(({ status }) => status === "failed").map((job) => describeBlockJob("block-summary", job)),
|
|
8118
8266
|
...snapshot.extractionJobs.filter(({ status }) => status === "failed").map((job) => describeBlockJob("event-extraction", job)),
|
|
@@ -8121,7 +8269,7 @@ async function overview(runtime, cachedEntries) {
|
|
|
8121
8269
|
const processingJobDetails = [
|
|
8122
8270
|
...snapshot.summaryJobs.filter(({ status, nextRetryAt }) => status === "pending" || status === "running" || status === "failed" && nextRetryAt !== null).map((job) => describeBlockJob("block-summary", job)),
|
|
8123
8271
|
...snapshot.extractionJobs.filter(({ status, nextRetryAt }) => status === "running" || status === "failed" && nextRetryAt !== null).map((job) => describeBlockJob("event-extraction", job)),
|
|
8124
|
-
...snapshot.graphProjectionJobs.filter(
|
|
8272
|
+
...snapshot.graphProjectionJobs.filter(graphProjectionIsProcessing).map(describeGraphJob)
|
|
8125
8273
|
];
|
|
8126
8274
|
const timestamps = [
|
|
8127
8275
|
...snapshot.blocks.map(({ createdAt }) => createdAt),
|
|
@@ -8454,7 +8602,7 @@ async function memories(runtime, url) {
|
|
|
8454
8602
|
return time(right).localeCompare(time(left));
|
|
8455
8603
|
}).map((event) => ({
|
|
8456
8604
|
...eventSummary(event, snapshot),
|
|
8457
|
-
relatedNodes: snapshot.graphNodes.filter(({ id
|
|
8605
|
+
relatedNodes: snapshot.graphNodes.filter(({ id }) => (event.temporal.participantNodeIds ?? []).includes(id)).map(({ id, name: name2, type, aliases }) => ({ id, name: name2, type, aliases })),
|
|
8458
8606
|
relatedElements: snapshot.elements.filter(({ sourceEventIds }) => sourceEventIds.includes(event.id)).map(({ id, name: name2 }) => ({ id, name: name2 }))
|
|
8459
8607
|
}));
|
|
8460
8608
|
else if (kind === "graph") {
|
|
@@ -8645,6 +8793,9 @@ async function sources(runtime, url) {
|
|
|
8645
8793
|
return {
|
|
8646
8794
|
namespace,
|
|
8647
8795
|
events: events.map((event) => eventSummary(event, eventId ? snapshot : void 0)),
|
|
8796
|
+
...eventId ? {
|
|
8797
|
+
relatedNodes: snapshot.graphNodes.filter(({ id }) => events[0]?.temporal.participantNodeIds?.includes(id)).map(({ id, name: name2, type, aliases }) => ({ id, name: name2, type, aliases }))
|
|
8798
|
+
} : {},
|
|
8648
8799
|
elements: elements.map(elementSummary),
|
|
8649
8800
|
blocks: events.map((event) => snapshot.blocks.find(({ id }) => id === event.sourceBlockId)).filter((block) => Boolean(block)).map((block) => ({ id: block.id, title: block.l0Title, createdAt: block.createdAt })),
|
|
8650
8801
|
messages: sourceMessages(snapshot, ids)
|