stratagate-dsh 0.2.68 → 0.2.70
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 +10 -0
- package/dist/client.js +19 -13
- package/dist/plugin.js +165 -25
- package/dist/plugin.js.map +1 -1
- package/package.json +2 -2
package/dist/plugin.js
CHANGED
|
@@ -1316,6 +1316,7 @@ function normalizeRetrievalAssessment(input, batchEvidenceRefs) {
|
|
|
1316
1316
|
// packages/core/src/storage.ts
|
|
1317
1317
|
var STRATAGATE_STORAGE_SCHEMA_VERSION = 10;
|
|
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"}`);
|
|
@@ -1467,6 +1468,9 @@ function normalizeSnapshot(value) {
|
|
|
1467
1468
|
if (!Array.isArray(snapshot[key])) throw new TypeError(`Invalid StrataGate snapshot: ${key} must be an array`);
|
|
1468
1469
|
}
|
|
1469
1470
|
if (!Array.isArray(snapshot.successfulModelResponses)) snapshot.successfulModelResponses = [];
|
|
1471
|
+
for (const job of snapshot.graphProjectionJobs) {
|
|
1472
|
+
if (job.nextRetryAt === void 0) job.nextRetryAt = null;
|
|
1473
|
+
}
|
|
1470
1474
|
for (const event of snapshot.events) {
|
|
1471
1475
|
event.temporal = { ...event.temporal, eventType: normalizeStandardEventType(event.temporal.eventType) };
|
|
1472
1476
|
}
|
|
@@ -2192,8 +2196,7 @@ var SqliteStorage = class {
|
|
|
2192
2196
|
externalMemoryImportJobs,
|
|
2193
2197
|
successfulModelResponses
|
|
2194
2198
|
};
|
|
2195
|
-
|
|
2196
|
-
return { snapshot: cloneSnapshot(snapshot), revision: space.revision };
|
|
2199
|
+
return { snapshot: cloneSnapshot(normalizeSnapshot(snapshot)), revision: space.revision };
|
|
2197
2200
|
}
|
|
2198
2201
|
async save(namespace, snapshot, expectedRevision) {
|
|
2199
2202
|
this.assertOpen();
|
|
@@ -2734,7 +2737,6 @@ var EXTERNAL_MEMORY_AUTO_APPLY_CONFIDENCE = 0.85;
|
|
|
2734
2737
|
function externalMemoryFingerprint(value) {
|
|
2735
2738
|
return `${normalizeSearchText(value.title)}\0${normalizeSearchText(value.summary)}`;
|
|
2736
2739
|
}
|
|
2737
|
-
var DERIVATION_MAX_ATTEMPTS = 3;
|
|
2738
2740
|
var DERIVATION_BACKOFF_MS = 1e3;
|
|
2739
2741
|
var StrataGate = class _StrataGate {
|
|
2740
2742
|
blockTurnSizeValue;
|
|
@@ -2919,6 +2921,7 @@ var StrataGate = class _StrataGate {
|
|
|
2919
2921
|
...job,
|
|
2920
2922
|
status: "failed",
|
|
2921
2923
|
lastError: "Graph projection was interrupted before completion.",
|
|
2924
|
+
nextRetryAt: memory.retryAt(job.attempts),
|
|
2922
2925
|
updatedAt: now
|
|
2923
2926
|
});
|
|
2924
2927
|
}
|
|
@@ -3077,6 +3080,7 @@ var StrataGate = class _StrataGate {
|
|
|
3077
3080
|
job.status = "pending";
|
|
3078
3081
|
job.attempts = 0;
|
|
3079
3082
|
job.lastError = null;
|
|
3083
|
+
job.nextRetryAt = null;
|
|
3080
3084
|
job.updatedAt = toUtc8Iso(this.now());
|
|
3081
3085
|
});
|
|
3082
3086
|
const batch = await this.claimGraphProjection(jobId);
|
|
@@ -3675,7 +3679,7 @@ var StrataGate = class _StrataGate {
|
|
|
3675
3679
|
}
|
|
3676
3680
|
async claimNextElementProjection() {
|
|
3677
3681
|
return this.commitMutation(() => {
|
|
3678
|
-
const job = [...this.elementProjectionJobs.values()].
|
|
3682
|
+
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
3683
|
if (!job) return null;
|
|
3680
3684
|
const events = job.sourceEventIds.flatMap((id) => this.events.find((event) => event.id === id) ?? []);
|
|
3681
3685
|
if (events.length === 0) {
|
|
@@ -3729,7 +3733,8 @@ var StrataGate = class _StrataGate {
|
|
|
3729
3733
|
}
|
|
3730
3734
|
async claimGraphProjection(jobId) {
|
|
3731
3735
|
return this.commitMutation(() => {
|
|
3732
|
-
const
|
|
3736
|
+
const now = this.now().getTime();
|
|
3737
|
+
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
3738
|
if (!job) return null;
|
|
3734
3739
|
const events = job.sourceEventIds.flatMap((id) => this.events.find((event) => event.id === id) ?? []);
|
|
3735
3740
|
if (events.length === 0) throw new Error(`Graph projection ${job.id} has no available source events`);
|
|
@@ -3744,14 +3749,14 @@ var StrataGate = class _StrataGate {
|
|
|
3744
3749
|
(event.temporal.participants ?? []).join(" ")
|
|
3745
3750
|
].join(" ")).join(" "));
|
|
3746
3751
|
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,
|
|
3752
|
+
const existingNodes = [...new Map(relevantNodes.map((node) => [node.id, node])).values()].slice(0, 32);
|
|
3748
3753
|
const nodeIds = new Set(existingNodes.map(({ id }) => id));
|
|
3749
3754
|
return {
|
|
3750
3755
|
jobId: job.id,
|
|
3751
3756
|
projectorVersion: job.projectorVersion,
|
|
3752
3757
|
events: structuredClone(events),
|
|
3753
3758
|
existingNodes: structuredClone(existingNodes),
|
|
3754
|
-
existingEdges: structuredClone(this.graphEdges.filter(({ fromNodeId, toNodeId }) => nodeIds.has(fromNodeId) && nodeIds.has(toNodeId)).slice(-
|
|
3759
|
+
existingEdges: structuredClone(this.graphEdges.filter(({ fromNodeId, toNodeId }) => nodeIds.has(fromNodeId) && nodeIds.has(toNodeId)).slice(-60))
|
|
3755
3760
|
};
|
|
3756
3761
|
});
|
|
3757
3762
|
}
|
|
@@ -3777,6 +3782,7 @@ var StrataGate = class _StrataGate {
|
|
|
3777
3782
|
job.edgeIds = touched.edgeIds;
|
|
3778
3783
|
job.reason = typeof result.reason === "string" ? result.reason.trim().replace(/\s+/g, " ").slice(0, 500) || null : null;
|
|
3779
3784
|
job.lastError = null;
|
|
3785
|
+
job.nextRetryAt = null;
|
|
3780
3786
|
job.updatedAt = toUtc8Iso(this.now());
|
|
3781
3787
|
return touched;
|
|
3782
3788
|
});
|
|
@@ -3787,6 +3793,7 @@ var StrataGate = class _StrataGate {
|
|
|
3787
3793
|
if (job.status === "completed") return;
|
|
3788
3794
|
job.status = "failed";
|
|
3789
3795
|
job.lastError = errorMessage(error);
|
|
3796
|
+
job.nextRetryAt = this.retryAt(job.attempts);
|
|
3790
3797
|
job.updatedAt = toUtc8Iso(this.now());
|
|
3791
3798
|
});
|
|
3792
3799
|
}
|
|
@@ -4169,6 +4176,7 @@ var StrataGate = class _StrataGate {
|
|
|
4169
4176
|
edgeIds: [],
|
|
4170
4177
|
reason: null,
|
|
4171
4178
|
lastError: null,
|
|
4179
|
+
nextRetryAt: null,
|
|
4172
4180
|
createdAt: now,
|
|
4173
4181
|
updatedAt: now
|
|
4174
4182
|
};
|
|
@@ -4991,6 +4999,48 @@ function renderBlocksForDiagnostics(blocks, finish) {
|
|
|
4991
4999
|
const rendered = blocks.map(renderBlockForDiagnostics).join("\n\n");
|
|
4992
5000
|
return rendered || `[no model blocks; finish=${finish}]`;
|
|
4993
5001
|
}
|
|
5002
|
+
function compactGraphProjectionContext(context) {
|
|
5003
|
+
const compactValue = (value) => Array.isArray(value) ? value.slice(0, 12).map((entry) => entry.slice(0, 160)) : value.slice(0, 400);
|
|
5004
|
+
return {
|
|
5005
|
+
jobId: context.jobId,
|
|
5006
|
+
projectorVersion: context.projectorVersion,
|
|
5007
|
+
events: context.events.map((event) => ({
|
|
5008
|
+
id: event.id,
|
|
5009
|
+
title: event.title,
|
|
5010
|
+
summary: event.summary,
|
|
5011
|
+
narrative: event.narrative,
|
|
5012
|
+
tags: event.tags,
|
|
5013
|
+
quotes: event.quotes,
|
|
5014
|
+
temporal: event.temporal,
|
|
5015
|
+
scope: event.scope,
|
|
5016
|
+
criticality: event.criticality,
|
|
5017
|
+
status: event.status
|
|
5018
|
+
})),
|
|
5019
|
+
existingNodes: context.existingNodes.slice(0, 32).map((node) => ({
|
|
5020
|
+
id: node.id,
|
|
5021
|
+
name: node.name,
|
|
5022
|
+
type: node.type,
|
|
5023
|
+
aliases: node.aliases.slice(0, 12),
|
|
5024
|
+
tags: node.tags?.slice(0, 12),
|
|
5025
|
+
currentState: node.currentState.slice(0, 600),
|
|
5026
|
+
facts: node.facts.filter(({ status }) => status === "active" || status === "disputed").slice(-12).map((fact) => ({
|
|
5027
|
+
key: fact.key,
|
|
5028
|
+
value: compactValue(fact.value),
|
|
5029
|
+
status: fact.status,
|
|
5030
|
+
sourceEventIds: fact.sourceEventIds.slice(-16)
|
|
5031
|
+
})),
|
|
5032
|
+
status: node.status,
|
|
5033
|
+
sourceEventIds: node.sourceEventIds.slice(-16)
|
|
5034
|
+
})),
|
|
5035
|
+
existingEdges: context.existingEdges.slice(-60).map((edge) => ({
|
|
5036
|
+
fromNodeId: edge.fromNodeId,
|
|
5037
|
+
toNodeId: edge.toNodeId,
|
|
5038
|
+
relation: edge.relation,
|
|
5039
|
+
status: edge.status,
|
|
5040
|
+
sourceEventIds: edge.sourceEventIds.slice(-16)
|
|
5041
|
+
}))
|
|
5042
|
+
};
|
|
5043
|
+
}
|
|
4994
5044
|
var DshModelBridge = class {
|
|
4995
5045
|
constructor(ctx, config) {
|
|
4996
5046
|
this.ctx = ctx;
|
|
@@ -5104,8 +5154,8 @@ var DshModelBridge = class {
|
|
|
5104
5154
|
const eventIds = new Set(context.events.map((event) => event.id));
|
|
5105
5155
|
const raw = object(await this.callStructured(
|
|
5106
5156
|
"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
|
|
5157
|
+
`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.`,
|
|
5158
|
+
compactGraphProjectionContext(context)
|
|
5109
5159
|
));
|
|
5110
5160
|
const nodes = (Array.isArray(raw.nodes) ? raw.nodes : []).flatMap((candidate) => {
|
|
5111
5161
|
const item = object(candidate);
|
|
@@ -5134,7 +5184,7 @@ var DshModelBridge = class {
|
|
|
5134
5184
|
...typeof item.confidence === "number" ? { confidence: item.confidence } : {},
|
|
5135
5185
|
sourceEventIds
|
|
5136
5186
|
}];
|
|
5137
|
-
});
|
|
5187
|
+
}).slice(0, 24);
|
|
5138
5188
|
const refs = new Set(nodes.map(({ ref }) => ref));
|
|
5139
5189
|
const edges = (Array.isArray(raw.edges) ? raw.edges : []).flatMap((candidate) => {
|
|
5140
5190
|
const item = object(candidate);
|
|
@@ -5153,7 +5203,7 @@ var DshModelBridge = class {
|
|
|
5153
5203
|
...typeof item.confidence === "number" ? { confidence: item.confidence } : {},
|
|
5154
5204
|
sourceEventIds
|
|
5155
5205
|
}];
|
|
5156
|
-
});
|
|
5206
|
+
}).slice(0, 32);
|
|
5157
5207
|
return { reason: text2(raw.reason, "Projected Event evidence into the Knowledge Graph."), nodes, edges };
|
|
5158
5208
|
};
|
|
5159
5209
|
externalMemoryDecider = async (context) => {
|
|
@@ -5197,7 +5247,9 @@ var DshModelBridge = class {
|
|
|
5197
5247
|
let useOff = await this.shouldUseOff(baseRoute);
|
|
5198
5248
|
let lastError;
|
|
5199
5249
|
let lastResponse = "";
|
|
5250
|
+
let attemptsUsed = 0;
|
|
5200
5251
|
for (let attempt = 1; attempt <= JSON_RESPONSE_ATTEMPTS; attempt += 1) {
|
|
5252
|
+
attemptsUsed = attempt;
|
|
5201
5253
|
const message = createUserMessage({
|
|
5202
5254
|
content: [{ type: "text", text: JSON.stringify(payload) }],
|
|
5203
5255
|
source: { kind: "plugin", plugin: "stratagate-memory" }
|
|
@@ -5306,13 +5358,14 @@ ${JSON_RETRY_INSTRUCTION}`,
|
|
|
5306
5358
|
`StrataGate ${STRUCTURED_TOOLS[kind].name} call was truncated before valid arguments`,
|
|
5307
5359
|
{ cause: error, response: responseForError }
|
|
5308
5360
|
) : error;
|
|
5361
|
+
if (kind === "graphProjector" && finish.kind === "max-tokens") break;
|
|
5309
5362
|
if (attempt < JSON_RESPONSE_ATTEMPTS) {
|
|
5310
5363
|
this.ctx.logger.warn(`stratagate-memory model returned an invalid structured tool call; retrying (${attempt}/${JSON_RESPONSE_ATTEMPTS})`);
|
|
5311
5364
|
}
|
|
5312
5365
|
}
|
|
5313
5366
|
}
|
|
5314
5367
|
throw new ModelJsonResponseError(
|
|
5315
|
-
`StrataGate model did not produce a valid ${STRUCTURED_TOOLS[kind].name} call after ${
|
|
5368
|
+
`StrataGate model did not produce a valid ${STRUCTURED_TOOLS[kind].name} call after ${attemptsUsed} attempt${attemptsUsed === 1 ? "" : "s"}`,
|
|
5316
5369
|
{ cause: lastError, response: lastResponse }
|
|
5317
5370
|
);
|
|
5318
5371
|
}
|
|
@@ -5715,6 +5768,9 @@ var DRAIN_BASE_BACKOFF_MS = 2e3;
|
|
|
5715
5768
|
var DRAIN_MAX_BACKOFF_MS = 6e4;
|
|
5716
5769
|
var BACKGROUND_WORKER_INITIAL_DELAY_MS = 250;
|
|
5717
5770
|
var BACKGROUND_WORKER_INTERVAL_MS = 3e3;
|
|
5771
|
+
function graphProjectionCanRun(job, now = Date.now()) {
|
|
5772
|
+
return job.attempts < DERIVATION_MAX_ATTEMPTS && (job.status === "pending" || job.status === "failed" && job.nextRetryAt != null && Date.parse(job.nextRetryAt) <= now);
|
|
5773
|
+
}
|
|
5718
5774
|
var AUTO_EVENT_LIMIT = 4;
|
|
5719
5775
|
var AUTO_ELEMENT_LIMIT = 4;
|
|
5720
5776
|
var AUTO_MEMORY_TOKEN_BUDGET = 900;
|
|
@@ -5849,7 +5905,7 @@ var StrataGateRuntime = class {
|
|
|
5849
5905
|
const runnable = [
|
|
5850
5906
|
...memory.listSummaryJobs(),
|
|
5851
5907
|
...memory.listExtractionJobs()
|
|
5852
|
-
].some((job) => job.status === "pending" || job.status === "failed" && job.nextRetryAt !== null && Date.parse(job.nextRetryAt) <= Date.now()) || memory.listGraphProjectionJobs().some((
|
|
5908
|
+
].some((job) => job.status === "pending" || job.status === "failed" && job.nextRetryAt !== null && Date.parse(job.nextRetryAt) <= Date.now()) || memory.listGraphProjectionJobs().some((job) => graphProjectionCanRun(job));
|
|
5853
5909
|
if (!runnable) return;
|
|
5854
5910
|
const hasActiveSessionWork = [
|
|
5855
5911
|
...this.derivationTimers.keys(),
|
|
@@ -6217,6 +6273,11 @@ var StrataGateRuntime = class {
|
|
|
6217
6273
|
retrievedMemories,
|
|
6218
6274
|
incremented: eventIds.size + elementIds.size,
|
|
6219
6275
|
evidenceRefs: selectedRefs,
|
|
6276
|
+
...assessment === void 0 ? {} : {
|
|
6277
|
+
verdict: assessment.verdict,
|
|
6278
|
+
missing: assessment.missing,
|
|
6279
|
+
nextStrategy: assessment.nextStrategy
|
|
6280
|
+
},
|
|
6220
6281
|
duplicateEvidenceRefs,
|
|
6221
6282
|
eventIds: [...eventIds],
|
|
6222
6283
|
elementIds: [...elementIds],
|
|
@@ -7122,7 +7183,7 @@ var StrataGateRuntime = class {
|
|
|
7122
7183
|
const namespace = this.namespaceFor(session);
|
|
7123
7184
|
if (this.closed || this.migrationTimers.has(namespace)) return;
|
|
7124
7185
|
if (typeof memory.listGraphProjectionJobs !== "function") return;
|
|
7125
|
-
const pending = memory.listGraphProjectionJobs().some((
|
|
7186
|
+
const pending = memory.listGraphProjectionJobs().some((job) => graphProjectionCanRun(job));
|
|
7126
7187
|
if (!pending) return;
|
|
7127
7188
|
const timer = setTimeout(() => {
|
|
7128
7189
|
this.migrationTimers.delete(namespace);
|
|
@@ -7828,6 +7889,10 @@ function currentPluginVersion() {
|
|
|
7828
7889
|
return "unknown";
|
|
7829
7890
|
}
|
|
7830
7891
|
var STRATAGATE_DSH_VERSION = currentPluginVersion();
|
|
7892
|
+
function graphProjectionIsProcessing(job) {
|
|
7893
|
+
if (job.status === "running") return true;
|
|
7894
|
+
return job.attempts < DERIVATION_MAX_ATTEMPTS && (job.status === "pending" || job.status === "failed" && job.nextRetryAt !== null);
|
|
7895
|
+
}
|
|
7831
7896
|
function installedPackageVersion(names) {
|
|
7832
7897
|
for (const name2 of names) {
|
|
7833
7898
|
try {
|
|
@@ -7908,7 +7973,81 @@ Tags: ${block.l0Tags.join(", ") || "none"}` },
|
|
|
7908
7973
|
{ level: 5, content: formatRawTranscript(block.l5Raw) }
|
|
7909
7974
|
]);
|
|
7910
7975
|
}
|
|
7911
|
-
function
|
|
7976
|
+
function sampledEventWeight(event, turn, lastAdoptedTurn, mentionCount) {
|
|
7977
|
+
return memoryWeightAt({
|
|
7978
|
+
status: event.status,
|
|
7979
|
+
weight: { ...event.weight, lastAdoptedTurn, mentionCount }
|
|
7980
|
+
}, turn);
|
|
7981
|
+
}
|
|
7982
|
+
function appendWeightSegment(points, event, fromTurn, toTurn, mentionCount) {
|
|
7983
|
+
if (toTurn < fromTurn) return;
|
|
7984
|
+
if (toTurn === fromTurn) return;
|
|
7985
|
+
const span = toTurn - fromTurn;
|
|
7986
|
+
const step = Math.max(1, Math.ceil(span / 32));
|
|
7987
|
+
for (let turn = fromTurn; turn < toTurn; turn += step) {
|
|
7988
|
+
points.push({ turn, weight: sampledEventWeight(event, turn, fromTurn, mentionCount), kind: "sample" });
|
|
7989
|
+
}
|
|
7990
|
+
points.push({ turn: toTurn, weight: sampledEventWeight(event, toTurn, fromTurn, mentionCount), kind: "sample" });
|
|
7991
|
+
}
|
|
7992
|
+
function eventWeightTrajectory(snapshot, event) {
|
|
7993
|
+
const currentTurn = snapshot.currentTurn;
|
|
7994
|
+
const effectiveAdoptions = Math.max(0, event.weight.mentionCount - 1);
|
|
7995
|
+
const adoptionReceipts = snapshot.usageReceipts.filter(({ eventIds }) => eventIds.includes(event.id));
|
|
7996
|
+
const adoptionTurns = adoptionReceipts.map(({ audit: audit2 }) => audit2?.turn).filter((turn) => Number.isSafeInteger(turn) && turn >= 0).sort((left, right) => left - right);
|
|
7997
|
+
const historyComplete = adoptionReceipts.length === effectiveAdoptions && adoptionTurns.length === adoptionReceipts.length && (effectiveAdoptions === 0 || adoptionTurns.at(-1) === event.weight.lastAdoptedTurn);
|
|
7998
|
+
const canInterpolate = event.status !== "forgotten" && event.status !== "archived" && event.weight.forcedCap === null && !event.weight.pinned;
|
|
7999
|
+
const points = [];
|
|
8000
|
+
if (canInterpolate && effectiveAdoptions === 0) {
|
|
8001
|
+
appendWeightSegment(points, event, event.weight.lastAdoptedTurn, currentTurn, 1);
|
|
8002
|
+
if (points.length > 0) {
|
|
8003
|
+
const first = points[0];
|
|
8004
|
+
points[0] = { turn: first.turn, weight: first.weight, kind: "creation", label: "\u521B\u5EFA" };
|
|
8005
|
+
}
|
|
8006
|
+
} else if (canInterpolate && historyComplete && adoptionTurns.length > 0) {
|
|
8007
|
+
let anchorTurn = adoptionTurns[0];
|
|
8008
|
+
let mentionCount = 2;
|
|
8009
|
+
points.push({ turn: anchorTurn, weight: 1, kind: "adoption", label: "\u91C7\u7528" });
|
|
8010
|
+
for (const [index, turn] of adoptionTurns.slice(1).entries()) {
|
|
8011
|
+
appendWeightSegment(points, event, anchorTurn, turn, mentionCount);
|
|
8012
|
+
points.push({ turn, weight: 1, kind: "adoption", label: index === adoptionTurns.length - 2 ? "\u518D\u6B21\u91C7\u7528" : "\u91C7\u7528" });
|
|
8013
|
+
anchorTurn = turn;
|
|
8014
|
+
mentionCount += 1;
|
|
8015
|
+
}
|
|
8016
|
+
appendWeightSegment(points, event, anchorTurn, currentTurn, mentionCount);
|
|
8017
|
+
} else if (canInterpolate) {
|
|
8018
|
+
appendWeightSegment(points, event, event.weight.lastAdoptedTurn, currentTurn, event.weight.mentionCount);
|
|
8019
|
+
if (effectiveAdoptions > 0 && points.length > 0) {
|
|
8020
|
+
const first = points[0];
|
|
8021
|
+
points[0] = { turn: first.turn, weight: first.weight, kind: "adoption", label: "\u6700\u8FD1\u91C7\u7528" };
|
|
8022
|
+
}
|
|
8023
|
+
}
|
|
8024
|
+
const currentWeight = memoryWeightAt(event, currentTurn);
|
|
8025
|
+
if (points.length === 0 || points.at(-1)?.turn !== currentTurn) {
|
|
8026
|
+
points.push({ turn: currentTurn, weight: currentWeight, kind: "current", label: "\u5F53\u524D" });
|
|
8027
|
+
} else if (points.at(-1)?.kind === "creation" || points.at(-1)?.kind === "adoption") {
|
|
8028
|
+
points[points.length - 1] = {
|
|
8029
|
+
...points[points.length - 1],
|
|
8030
|
+
weight: currentWeight,
|
|
8031
|
+
label: `${points[points.length - 1].label} \xB7 \u5F53\u524D`
|
|
8032
|
+
};
|
|
8033
|
+
} else {
|
|
8034
|
+
points[points.length - 1] = { ...points[points.length - 1], weight: currentWeight, kind: "current", label: "\u5F53\u524D" };
|
|
8035
|
+
}
|
|
8036
|
+
return {
|
|
8037
|
+
scale: "conversation_turn",
|
|
8038
|
+
currentTurn,
|
|
8039
|
+
currentWeight,
|
|
8040
|
+
effectiveAdoptions,
|
|
8041
|
+
latestAdoptionTurn: effectiveAdoptions > 0 ? event.weight.lastAdoptedTurn : null,
|
|
8042
|
+
turnsSinceLatestAdoption: effectiveAdoptions > 0 ? Math.max(0, currentTurn - event.weight.lastAdoptedTurn) : null,
|
|
8043
|
+
lastRetrievedAt: event.weight.lastRetrievedAt,
|
|
8044
|
+
recordedAdoptionTurns: adoptionTurns,
|
|
8045
|
+
historyComplete,
|
|
8046
|
+
points,
|
|
8047
|
+
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" : effectiveAdoptions > 0 && !historyComplete ? "\u90E8\u5206\u65E9\u671F\u91C7\u7528\u8BB0\u5F55\u7F3A\u5C11\u8F6E\u6B21\uFF1B\u66F2\u7EBF\u4EC5\u4ECE\u6700\u8FD1\u4E00\u6B21\u53EF\u786E\u8BA4\u7684\u5F3A\u5316\u5F00\u59CB\u3002" : effectiveAdoptions > 0 ? "\u91C7\u7528\u8F6E\u6B21\u6765\u81EA\u4F7F\u7528\u56DE\u6267\uFF1B\u521B\u5EFA\u8F6E\u6B21\u672A\u5355\u72EC\u4FDD\u5B58\uFF0C\u56E0\u6B64\u4E0D\u63A8\u6D4B\u521B\u5EFA\u8282\u70B9\u3002" : "\u5C1A\u672A\u53D1\u751F\u6709\u6548\u91C7\u7528\uFF1B\u521B\u5EFA\u951A\u70B9\u6765\u81EA Event \u5F53\u524D\u6743\u91CD\u72B6\u6001\u3002"
|
|
8048
|
+
};
|
|
8049
|
+
}
|
|
8050
|
+
function eventSummary(event, snapshot) {
|
|
7912
8051
|
return {
|
|
7913
8052
|
id: event.id,
|
|
7914
8053
|
title: event.title,
|
|
@@ -7924,6 +8063,7 @@ function eventSummary(event) {
|
|
|
7924
8063
|
status: event.status,
|
|
7925
8064
|
supersededBy: event.supersededBy,
|
|
7926
8065
|
weight: event.weight,
|
|
8066
|
+
...snapshot ? { weightTrajectory: eventWeightTrajectory(snapshot, event) } : {},
|
|
7927
8067
|
createdAt: event.createdAt,
|
|
7928
8068
|
updatedAt: event.updatedAt
|
|
7929
8069
|
};
|
|
@@ -8020,7 +8160,7 @@ async function overview(runtime, cachedEntries) {
|
|
|
8020
8160
|
kind: "graph-projection",
|
|
8021
8161
|
status: job.status,
|
|
8022
8162
|
attempts: job.attempts,
|
|
8023
|
-
nextRetryAt:
|
|
8163
|
+
nextRetryAt: job.nextRetryAt,
|
|
8024
8164
|
lastError: job.lastError?.slice(0, 500) ?? null,
|
|
8025
8165
|
lastErrorFull: job.lastError,
|
|
8026
8166
|
updatedAt: job.updatedAt,
|
|
@@ -8032,7 +8172,7 @@ async function overview(runtime, cachedEntries) {
|
|
|
8032
8172
|
};
|
|
8033
8173
|
};
|
|
8034
8174
|
const failedJobs = snapshot.summaryJobs.filter(({ status }) => status === "failed").length + snapshot.extractionJobs.filter(({ status }) => status === "failed").length + snapshot.graphProjectionJobs.filter(({ status }) => status === "failed").length;
|
|
8035
|
-
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(
|
|
8175
|
+
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;
|
|
8036
8176
|
const failedJobDetails = [
|
|
8037
8177
|
...snapshot.summaryJobs.filter(({ status }) => status === "failed").map((job) => describeBlockJob("block-summary", job)),
|
|
8038
8178
|
...snapshot.extractionJobs.filter(({ status }) => status === "failed").map((job) => describeBlockJob("event-extraction", job)),
|
|
@@ -8041,7 +8181,7 @@ async function overview(runtime, cachedEntries) {
|
|
|
8041
8181
|
const processingJobDetails = [
|
|
8042
8182
|
...snapshot.summaryJobs.filter(({ status, nextRetryAt }) => status === "pending" || status === "running" || status === "failed" && nextRetryAt !== null).map((job) => describeBlockJob("block-summary", job)),
|
|
8043
8183
|
...snapshot.extractionJobs.filter(({ status, nextRetryAt }) => status === "running" || status === "failed" && nextRetryAt !== null).map((job) => describeBlockJob("event-extraction", job)),
|
|
8044
|
-
...snapshot.graphProjectionJobs.filter(
|
|
8184
|
+
...snapshot.graphProjectionJobs.filter(graphProjectionIsProcessing).map(describeGraphJob)
|
|
8045
8185
|
];
|
|
8046
8186
|
const timestamps = [
|
|
8047
8187
|
...snapshot.blocks.map(({ createdAt }) => createdAt),
|
|
@@ -8373,7 +8513,7 @@ async function memories(runtime, url) {
|
|
|
8373
8513
|
const time = (event) => event.temporal.happenedStart ?? event.temporal.happenedEnd ?? event.temporal.mentionedAt ?? event.createdAt;
|
|
8374
8514
|
return time(right).localeCompare(time(left));
|
|
8375
8515
|
}).map((event) => ({
|
|
8376
|
-
...eventSummary(event),
|
|
8516
|
+
...eventSummary(event, snapshot),
|
|
8377
8517
|
relatedNodes: snapshot.graphNodes.filter(({ id, sourceEventIds }) => sourceEventIds.includes(event.id) || (event.temporal.participantNodeIds ?? []).includes(id)).map(({ id, name: name2, type }) => ({ id, name: name2, type })),
|
|
8378
8518
|
relatedElements: snapshot.elements.filter(({ sourceEventIds }) => sourceEventIds.includes(event.id)).map(({ id, name: name2 }) => ({ id, name: name2 }))
|
|
8379
8519
|
}));
|
|
@@ -8385,7 +8525,7 @@ async function memories(runtime, url) {
|
|
|
8385
8525
|
projectorVersion: KNOWLEDGE_GRAPH_PROJECTOR_VERSION,
|
|
8386
8526
|
nodes: snapshot.graphNodes.map((node) => ({
|
|
8387
8527
|
...node,
|
|
8388
|
-
supportingEvents: node.sourceEventIds.flatMap((id) => eventMap.get(id) ?? []).map(eventSummary)
|
|
8528
|
+
supportingEvents: node.sourceEventIds.flatMap((id) => eventMap.get(id) ?? []).map((event) => eventSummary(event))
|
|
8389
8529
|
})),
|
|
8390
8530
|
edges: snapshot.graphEdges,
|
|
8391
8531
|
clusters: clusterKnowledgeGraph(snapshot.graphNodes, snapshot.graphEdges),
|
|
@@ -8474,7 +8614,7 @@ async function memories(runtime, url) {
|
|
|
8474
8614
|
jobs: projections.length,
|
|
8475
8615
|
lastError: failedProjection?.lastError ?? null
|
|
8476
8616
|
} : null,
|
|
8477
|
-
relatedEvents: relatedEvents.map(eventSummary),
|
|
8617
|
+
relatedEvents: relatedEvents.map((event) => eventSummary(event)),
|
|
8478
8618
|
relatedNodes
|
|
8479
8619
|
};
|
|
8480
8620
|
});
|
|
@@ -8533,7 +8673,7 @@ async function sources(runtime, url) {
|
|
|
8533
8673
|
node,
|
|
8534
8674
|
nodes: snapshot.graphNodes.filter(({ id }) => relatedNodeIds.has(id)),
|
|
8535
8675
|
edges,
|
|
8536
|
-
events: events.map(eventSummary),
|
|
8676
|
+
events: events.map((event) => eventSummary(event)),
|
|
8537
8677
|
messages: sourceMessages(snapshot, ids)
|
|
8538
8678
|
};
|
|
8539
8679
|
} else if (elementId) {
|
|
@@ -8553,7 +8693,7 @@ async function sources(runtime, url) {
|
|
|
8553
8693
|
elements = snapshot.elements.filter(({ sourceEventIds }) => sourceEventIds.some((id) => eventIds.has(id)));
|
|
8554
8694
|
return {
|
|
8555
8695
|
namespace,
|
|
8556
|
-
events: events.map(eventSummary),
|
|
8696
|
+
events: events.map((event) => eventSummary(event)),
|
|
8557
8697
|
elements: elements.map(elementSummary),
|
|
8558
8698
|
messages: sourceMessages(snapshot, ids),
|
|
8559
8699
|
layers: displayBlock ? virtualBlockLayers(displayBlock) : blockLayers(block),
|
|
@@ -8564,7 +8704,7 @@ async function sources(runtime, url) {
|
|
|
8564
8704
|
}
|
|
8565
8705
|
return {
|
|
8566
8706
|
namespace,
|
|
8567
|
-
events: events.map(eventSummary),
|
|
8707
|
+
events: events.map((event) => eventSummary(event, eventId ? snapshot : void 0)),
|
|
8568
8708
|
elements: elements.map(elementSummary),
|
|
8569
8709
|
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 })),
|
|
8570
8710
|
messages: sourceMessages(snapshot, ids)
|
|
@@ -8624,7 +8764,7 @@ function receiptSources(snapshot, receipt) {
|
|
|
8624
8764
|
const messageIds = new Set(supportingEvents.flatMap(({ sourceMessageIds }) => sourceMessageIds));
|
|
8625
8765
|
return {
|
|
8626
8766
|
...receipt,
|
|
8627
|
-
events: events.map(eventSummary),
|
|
8767
|
+
events: events.map((event) => eventSummary(event)),
|
|
8628
8768
|
elements: elements.map(elementSummary),
|
|
8629
8769
|
sourceMessages: sourceMessages(snapshot, messageIds)
|
|
8630
8770
|
};
|