stratagate-dsh 0.3.13 → 0.3.15
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 +2 -2
- package/dist/plugin.js +63 -29
- package/dist/plugin.js.map +1 -1
- package/docs/npm-release.md +52 -0
- package/package.json +1 -1
- package/docs/validation/first-login-graph-warning-20261013/render-comparison.json +0 -58
- package/docs/validation/first-login-graph-warning-20261013/tests.after.json +0 -1
- package/docs/validation/issue119-after.json +0 -30
- package/docs/validation/issue119-before.json +0 -94
package/dist/plugin.js
CHANGED
|
@@ -1689,6 +1689,7 @@ var PROFILE_FIELDS = {
|
|
|
1689
1689
|
persistentNotes: { label: "Persistent notes", maxLength: 1200 }
|
|
1690
1690
|
};
|
|
1691
1691
|
var PROFILE_PROTECTED_SHORT_FIELDS = ["userPreferredName", "assistantPreferredName", "preferredLanguage", "reasoningLanguage", "defaultLocation", "homeCity", "currentCity"];
|
|
1692
|
+
var PROFILE_MAINTAINABLE_FIELDS = Object.keys(PROFILE_FIELDS).filter((field) => !PROFILE_PROTECTED_SHORT_FIELDS.includes(field));
|
|
1692
1693
|
var PROFILE_TOTAL_MAX_LENGTH = 6e3;
|
|
1693
1694
|
var PROFILE_MAINTENANCE_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
1694
1695
|
var PROFILE_MAINTENANCE_TOTAL_THRESHOLD = 4800;
|
|
@@ -1714,8 +1715,9 @@ function validateProfile(profile) {
|
|
|
1714
1715
|
function profileMaintenanceDue(profile, timeBasisAt, now = Date.now()) {
|
|
1715
1716
|
const lengths = Object.keys(PROFILE_FIELDS).map((field) => ({ field, length: profileLength(profile[field]) }));
|
|
1716
1717
|
const total = lengths.reduce((sum, item) => sum + item.length, 0);
|
|
1717
|
-
|
|
1718
|
-
|
|
1718
|
+
const maintainableLengths = lengths.filter(({ field }) => PROFILE_MAINTAINABLE_FIELDS.includes(field));
|
|
1719
|
+
if (!maintainableLengths.some(({ length }) => length > 0)) return false;
|
|
1720
|
+
return timeBasisAt !== null && now - Date.parse(timeBasisAt) >= PROFILE_MAINTENANCE_INTERVAL_MS || total >= PROFILE_MAINTENANCE_TOTAL_THRESHOLD || maintainableLengths.some(({ field, length }) => length >= PROFILE_FIELDS[field].maxLength * 0.8);
|
|
1719
1721
|
}
|
|
1720
1722
|
function renderPersistentProfile(profile) {
|
|
1721
1723
|
const lines = Object.keys(PROFILE_FIELDS).filter((field) => profile[field].length > 0).map((field) => `${PROFILE_FIELDS[field].label}: ${profile[field]}`);
|
|
@@ -4279,7 +4281,9 @@ var SqliteStorage = class _SqliteStorage {
|
|
|
4279
4281
|
if (failed?.input_json === JSON.stringify(profile) && now < Date.parse(failed.next_retry_at)) return false;
|
|
4280
4282
|
const state = this.getProfileMaintenanceState();
|
|
4281
4283
|
if (!profileMaintenanceDue(profile, state?.lastSucceededAt ?? this.getProfileMaintenanceStartedAt(), now)) return false;
|
|
4282
|
-
|
|
4284
|
+
if (!state) return true;
|
|
4285
|
+
const maintained = JSON.parse(state.inputJson);
|
|
4286
|
+
return PROFILE_MAINTAINABLE_FIELDS.some((field) => maintained[field] !== profile[field]);
|
|
4283
4287
|
}
|
|
4284
4288
|
writeProfileField(field, oldValue, newValue, source, sourceMessageId, now = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
4285
4289
|
this.database.prepare("INSERT INTO persistent_profile (field, value) VALUES (?, ?) ON CONFLICT (field) DO UPDATE SET value = excluded.value").run(field, newValue);
|
|
@@ -5497,6 +5501,7 @@ function agentEventCandidate(content, category, now, threadId) {
|
|
|
5497
5501
|
};
|
|
5498
5502
|
}
|
|
5499
5503
|
var DERIVATION_BACKOFF_MS = 1e3;
|
|
5504
|
+
var GRAPH_PROJECTION_BATCH_SIZE = 8;
|
|
5500
5505
|
function restrictExtractionRelations(temporal, allowedIds) {
|
|
5501
5506
|
const result = { ...temporal };
|
|
5502
5507
|
if (typeof result.sameEventId !== "string" || !allowedIds.has(result.sameEventId)) {
|
|
@@ -6665,6 +6670,18 @@ var StrataGate = class _StrataGate {
|
|
|
6665
6670
|
return this.commitMutation(() => {
|
|
6666
6671
|
const job = [...this.graphProjectionJobs.values()].filter(eligible).sort((left, right) => Number(left.status !== "pending") - Number(right.status !== "pending") || right.priority - left.priority || left.createdAt.localeCompare(right.createdAt))[0];
|
|
6667
6672
|
if (!job) return null;
|
|
6673
|
+
const sourceEventIds = job.sourceEventIds;
|
|
6674
|
+
for (let index = GRAPH_PROJECTION_BATCH_SIZE; index < sourceEventIds.length; index += GRAPH_PROJECTION_BATCH_SIZE) {
|
|
6675
|
+
const id = this.graphIdFactory("gproj");
|
|
6676
|
+
this.graphProjectionJobs.set(id, {
|
|
6677
|
+
...job,
|
|
6678
|
+
id,
|
|
6679
|
+
sourceEventIds: sourceEventIds.slice(index, index + GRAPH_PROJECTION_BATCH_SIZE),
|
|
6680
|
+
nodeIds: [],
|
|
6681
|
+
edgeIds: []
|
|
6682
|
+
});
|
|
6683
|
+
}
|
|
6684
|
+
job.sourceEventIds = sourceEventIds.slice(0, GRAPH_PROJECTION_BATCH_SIZE);
|
|
6668
6685
|
const events = job.sourceEventIds.flatMap((id) => {
|
|
6669
6686
|
const event = this.findEvent(id);
|
|
6670
6687
|
return event ? [event] : [];
|
|
@@ -7550,30 +7567,30 @@ var StrataGate = class _StrataGate {
|
|
|
7550
7567
|
return job;
|
|
7551
7568
|
}
|
|
7552
7569
|
queueGraphProjection(sourceEventIds, priority) {
|
|
7553
|
-
if (!this.graphProjector) return
|
|
7554
|
-
const completed = new Set([...this.graphProjectionJobs.values()].filter((
|
|
7555
|
-
const queued = new Set([...this.graphProjectionJobs.values()].filter((
|
|
7570
|
+
if (!this.graphProjector) return;
|
|
7571
|
+
const completed = new Set([...this.graphProjectionJobs.values()].filter((job) => job.projectorVersion === KNOWLEDGE_GRAPH_PROJECTOR_VERSION && job.status === "completed").flatMap((job) => job.sourceEventIds));
|
|
7572
|
+
const queued = new Set([...this.graphProjectionJobs.values()].filter((job) => job.projectorVersion === KNOWLEDGE_GRAPH_PROJECTOR_VERSION && job.status !== "completed").flatMap((job) => job.sourceEventIds));
|
|
7556
7573
|
const ids2 = [...new Set(sourceEventIds.filter((id) => this.findEvent(id) && !completed.has(id) && !queued.has(id)))];
|
|
7557
|
-
if (ids2.length === 0) return null;
|
|
7558
7574
|
const now = toUtc8Iso(this.now());
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7575
|
-
|
|
7576
|
-
|
|
7575
|
+
for (let index = 0; index < ids2.length; index += GRAPH_PROJECTION_BATCH_SIZE) {
|
|
7576
|
+
const job = {
|
|
7577
|
+
id: this.graphIdFactory("gproj"),
|
|
7578
|
+
sourceEventIds: ids2.slice(index, index + GRAPH_PROJECTION_BATCH_SIZE),
|
|
7579
|
+
projectorVersion: KNOWLEDGE_GRAPH_PROJECTOR_VERSION,
|
|
7580
|
+
status: "pending",
|
|
7581
|
+
attempts: 0,
|
|
7582
|
+
priority,
|
|
7583
|
+
nodeIds: [],
|
|
7584
|
+
edgeIds: [],
|
|
7585
|
+
nameProvenanceRecoveryVersion: 1,
|
|
7586
|
+
reason: null,
|
|
7587
|
+
lastError: null,
|
|
7588
|
+
nextRetryAt: null,
|
|
7589
|
+
createdAt: now,
|
|
7590
|
+
updatedAt: now
|
|
7591
|
+
};
|
|
7592
|
+
this.graphProjectionJobs.set(job.id, job);
|
|
7593
|
+
}
|
|
7577
7594
|
}
|
|
7578
7595
|
recoverGraphNameProvenanceFailures() {
|
|
7579
7596
|
for (const job of this.graphProjectionJobs.values()) {
|
|
@@ -7591,8 +7608,8 @@ var StrataGate = class _StrataGate {
|
|
|
7591
7608
|
const score = (event) => (event.status === "active" ? 1e4 : 0) + event.weight.mentionCount * 100 + (event.scope === "project" ? 500 : 0) + (Date.parse(event.temporal.happenedStart ?? event.temporal.mentionedAt ?? event.updatedAt) || 0) / 1e12;
|
|
7592
7609
|
return score(right) - score(left);
|
|
7593
7610
|
});
|
|
7594
|
-
for (let index = 0; index < candidates.length; index +=
|
|
7595
|
-
this.queueGraphProjection(candidates.slice(index, index +
|
|
7611
|
+
for (let index = 0; index < candidates.length; index += GRAPH_PROJECTION_BATCH_SIZE) {
|
|
7612
|
+
this.queueGraphProjection(candidates.slice(index, index + GRAPH_PROJECTION_BATCH_SIZE).map(({ id }) => id), candidates.length - index);
|
|
7596
7613
|
}
|
|
7597
7614
|
}
|
|
7598
7615
|
queueElementProjection(sourceEventIds) {
|
|
@@ -9052,6 +9069,7 @@ function parseTopicProjection(value, context) {
|
|
|
9052
9069
|
return { topics };
|
|
9053
9070
|
}
|
|
9054
9071
|
var TOPIC_OUTPUT_TOKEN_BUDGET = 32768;
|
|
9072
|
+
var GRAPH_OUTPUT_TOKEN_BUDGET = 32768;
|
|
9055
9073
|
var DshModelBridge = class {
|
|
9056
9074
|
constructor(ctx, config, liveStructuredReasoningEffort) {
|
|
9057
9075
|
this.ctx = ctx;
|
|
@@ -9387,6 +9405,7 @@ Use project scope for repository decisions, user scope for stable preferences/id
|
|
|
9387
9405
|
const routeKey = `${baseRoute.provider}\0${baseRoute.model}`;
|
|
9388
9406
|
let useOff = await this.shouldUseOff(baseRoute);
|
|
9389
9407
|
const isTopic = kind === "topicProjector";
|
|
9408
|
+
const isGraph = kind === "graphProjector";
|
|
9390
9409
|
const topicDiagnostics = {
|
|
9391
9410
|
...topicMetadata,
|
|
9392
9411
|
requestedOutputTokens: TOPIC_OUTPUT_TOKEN_BUDGET,
|
|
@@ -9413,7 +9432,7 @@ Use project scope for repository decisions, user scope for stable preferences/id
|
|
|
9413
9432
|
}
|
|
9414
9433
|
}
|
|
9415
9434
|
const message = createUserMessage({
|
|
9416
|
-
content: [{ type: "text", text: JSON.stringify(payload) }],
|
|
9435
|
+
content: [{ type: "text", text: JSON.stringify(isGraph ? { ...object(payload), outputTokenBudget: GRAPH_OUTPUT_TOKEN_BUDGET } : payload) }],
|
|
9417
9436
|
source: dshMessageSource()
|
|
9418
9437
|
});
|
|
9419
9438
|
const assembler = new BlockAssembler();
|
|
@@ -9433,7 +9452,7 @@ ${JSON_RETRY_INSTRUCTION}${graphRetryFeedback}${topicRetryFeedback}`,
|
|
|
9433
9452
|
type: "function",
|
|
9434
9453
|
function: { name: STRUCTURED_TOOLS[kind].name }
|
|
9435
9454
|
},
|
|
9436
|
-
maxTokens: kind === "dreamingStep" ? TOPIC_OUTPUT_TOKEN_BUDGET : kind === "profileMaintenance" ? Math.max(this.config.maxOutputTokens, Math.min(12e3, 512 + 2 * Array.from(JSON.stringify(payload)).length)) : isTopic ? TOPIC_OUTPUT_TOKEN_BUDGET : this.config.maxOutputTokens,
|
|
9455
|
+
maxTokens: kind === "dreamingStep" ? TOPIC_OUTPUT_TOKEN_BUDGET : kind === "profileMaintenance" ? Math.max(this.config.maxOutputTokens, Math.min(12e3, 512 + 2 * Array.from(JSON.stringify(payload)).length)) : isTopic ? TOPIC_OUTPUT_TOKEN_BUDGET : isGraph ? GRAPH_OUTPUT_TOKEN_BUDGET : this.config.maxOutputTokens,
|
|
9437
9456
|
sessionId: execution.sessionId,
|
|
9438
9457
|
purpose: "compaction"
|
|
9439
9458
|
};
|
|
@@ -9445,6 +9464,18 @@ ${JSON_RETRY_INSTRUCTION}${graphRetryFeedback}${topicRetryFeedback}`,
|
|
|
9445
9464
|
request.maxTokens = Math.min(TOPIC_OUTPUT_TOKEN_BUDGET, Math.floor(window - input - 1024));
|
|
9446
9465
|
}
|
|
9447
9466
|
}
|
|
9467
|
+
if (isGraph) {
|
|
9468
|
+
const input = estimateTokens(JSON.stringify({ system: request.system, tools: request.tools, messages: request.messages }));
|
|
9469
|
+
const window = this.contextWindows.get(routeKey);
|
|
9470
|
+
if (window !== void 0) {
|
|
9471
|
+
if (window - input - 1024 < 256) throw new Error("Graph input exceeds model context capacity; reduce the source batch");
|
|
9472
|
+
request.maxTokens = Math.min(GRAPH_OUTPUT_TOKEN_BUDGET, Math.floor(window - input - 1024));
|
|
9473
|
+
}
|
|
9474
|
+
request.messages = [{ ...message, content: [{ type: "text", text: JSON.stringify({
|
|
9475
|
+
...object(payload),
|
|
9476
|
+
outputTokenBudget: request.maxTokens
|
|
9477
|
+
}) }] }];
|
|
9478
|
+
}
|
|
9448
9479
|
if (isTopic) {
|
|
9449
9480
|
const estimateInput = () => estimateTokens(JSON.stringify({ system: request.system, tools: request.tools, messages: request.messages }));
|
|
9450
9481
|
let inputTokens = estimateInput();
|
|
@@ -9522,6 +9553,9 @@ ${JSON_RETRY_INSTRUCTION}${graphRetryFeedback}${topicRetryFeedback}`,
|
|
|
9522
9553
|
[finish=${finish.kind}; toolCalls=${calls.length}]`;
|
|
9523
9554
|
lastResponse = responseForError;
|
|
9524
9555
|
try {
|
|
9556
|
+
if (isGraph && finish.kind === "max-tokens") {
|
|
9557
|
+
throw new ModelJsonResponseError("StrataGate Graph output token limit reached", { response: responseForError });
|
|
9558
|
+
}
|
|
9525
9559
|
const expectedTool = STRUCTURED_TOOLS[kind].name;
|
|
9526
9560
|
let parsed;
|
|
9527
9561
|
if (calls.length !== 1 || calls[0]?.name !== expectedTool) {
|