stratagate-dsh 0.2.30 → 0.2.31
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 +3 -0
- package/dist/client.js +6 -2
- package/dist/index.js +430 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -132,14 +132,14 @@ function resultSummary(value) {
|
|
|
132
132
|
}
|
|
133
133
|
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
134
134
|
if (!value || typeof value !== "object") return "";
|
|
135
|
-
const
|
|
136
|
-
if (typeof
|
|
137
|
-
if (typeof
|
|
138
|
-
if (typeof
|
|
139
|
-
const counts = Object.entries(
|
|
135
|
+
const record2 = value;
|
|
136
|
+
if (typeof record2.error === "string") return `failed: ${record2.error.replace(/\s+/g, " ").slice(0, 140)}`;
|
|
137
|
+
if (typeof record2.summary === "string") return record2.summary.replace(/\s+/g, " ").slice(0, 160);
|
|
138
|
+
if (typeof record2.message === "string") return record2.message.replace(/\s+/g, " ").slice(0, 160);
|
|
139
|
+
const counts = Object.entries(record2).filter(([key, item]) => !["arguments", "params", "input", "request"].includes(key) && Array.isArray(item)).map(([key, item]) => `${key}: ${item.length}`);
|
|
140
140
|
if (counts.length > 0) return counts.join(", ").slice(0, 160);
|
|
141
|
-
if (
|
|
142
|
-
if (
|
|
141
|
+
if (record2.ok === true) return "completed";
|
|
142
|
+
if (record2.ok === false) return "not completed";
|
|
143
143
|
return "structured result returned";
|
|
144
144
|
}
|
|
145
145
|
function summarizeToolTrace(trace) {
|
|
@@ -157,14 +157,14 @@ function summarizeToolJson(value) {
|
|
|
157
157
|
item.forEach(visit);
|
|
158
158
|
return;
|
|
159
159
|
}
|
|
160
|
-
const
|
|
161
|
-
if (typeof
|
|
162
|
-
if (typeof
|
|
163
|
-
if (
|
|
164
|
-
const name2 =
|
|
160
|
+
const record2 = item;
|
|
161
|
+
if (typeof record2.name === "string" && ("arguments" in record2 || "parameters" in record2)) names.add(record2.name);
|
|
162
|
+
if (typeof record2.tool === "string") names.add(record2.tool);
|
|
163
|
+
if (record2.function && typeof record2.function === "object") {
|
|
164
|
+
const name2 = record2.function.name;
|
|
165
165
|
if (typeof name2 === "string") names.add(name2);
|
|
166
166
|
}
|
|
167
|
-
Object.values(
|
|
167
|
+
Object.values(record2).forEach(visit);
|
|
168
168
|
};
|
|
169
169
|
visit(parsed);
|
|
170
170
|
if (names.size === 0) return null;
|
|
@@ -505,6 +505,235 @@ function normalizeStandardEventType(value) {
|
|
|
505
505
|
return aliases[normalized] ?? "other";
|
|
506
506
|
}
|
|
507
507
|
|
|
508
|
+
// ../../src/external-memory.ts
|
|
509
|
+
var EXTERNAL_MEMORY_EXPORT_SCHEMA = "stratagate.external-memory.v2";
|
|
510
|
+
var EXTERNAL_MEMORY_DECIDER_PROMPT_ZH_CN = `
|
|
511
|
+
\u4F60\u662F StrataGate \u7684\u5916\u90E8\u8BB0\u5FC6\u5408\u5E76\u88C1\u51B3\u5668\u3002\u8F93\u5165\u5305\u542B\u4E00\u4E2A\u5916\u90E8 candidate Event\uFF0C\u4EE5\u53CA\u672C\u5730\u68C0\u7D22\u5F97\u5230\u7684 Top-K existing Events\u3002\u53EA\u80FD\u4F9D\u636E candidate \u548C existing Events \u5224\u65AD\uFF0C\u4E0D\u5F97\u5F15\u5165\u5217\u8868\u4E4B\u5916\u7684\u672C\u5730\u4E8B\u4EF6\uFF0C\u4E5F\u4E0D\u5F97\u51ED\u5E38\u8BC6\u8865\u5168\u65F6\u95F4\u3002
|
|
512
|
+
|
|
513
|
+
action \u53EA\u80FD\u662F\uFF1A
|
|
514
|
+
- ADD\uFF1A\u6CA1\u6709\u8DB3\u591F\u76F8\u540C\u6216\u53EF\u66F4\u65B0\u7684\u672C\u5730\u4E8B\u4EF6\u3002
|
|
515
|
+
- MERGE\uFF1Acandidate \u4E0E\u4E00\u4E2A\u6216\u591A\u4E2A existing Events \u8868\u8FBE\u540C\u4E00\u4E8B\u5B9E\u7684\u8865\u5145\u6216\u6574\u5408\uFF1B\u8FD4\u56DE\u4E00\u6761\u66F4\u5B8C\u6574\u7684 mergedCandidate\uFF0C\u5E76\u5F15\u7528\u8981\u88AB\u65B0\u4E8B\u5B9E\u53D6\u4EE3\u7684 existingEventIds\u3002
|
|
516
|
+
- SUPERSEDE\uFF1Acandidate \u660E\u786E\u662F\u540C\u4E00\u4E8B\u5B9E\u7684\u8F83\u65B0\u7248\u672C\u3001\u7EA0\u6B63\u6216\u72B6\u6001\u66F4\u65B0\uFF1B\u5F15\u7528\u88AB\u53D6\u4EE3\u7684 existingEventIds\u3002
|
|
517
|
+
- CONFLICT\uFF1A\u4E24\u6761\u9648\u8FF0\u90FD\u5E94\u4FDD\u7559\uFF0C\u4F46\u5185\u5BB9\u65E0\u6CD5\u540C\u65F6\u6210\u7ACB\uFF1B\u5F15\u7528\u51B2\u7A81\u7684 existingEventIds\u3002
|
|
518
|
+
- IGNORE\uFF1A\u91CD\u590D\u3001\u4E34\u65F6\u3001\u65E0\u957F\u671F\u4EF7\u503C\u3001\u8BC1\u636E\u4E0D\u8DB3\uFF0C\u6216\u65E0\u6CD5\u5B89\u5168\u5224\u65AD\u3002
|
|
519
|
+
|
|
520
|
+
\u65F6\u95F4\u88C1\u51B3\uFF1A\u5916\u90E8 candidate \u7684\u65F6\u95F4\u5B57\u6BB5\u53EA\u5728\u5176\u81EA\u8EAB\u6709\u660E\u786E\u4F9D\u636E\u65F6\u4FDD\u7559\u3002\u4E0D\u8981\u56E0\u4E3A candidate \u8F83\u65B0\u5C31\u5047\u8BBE\u5B83\u53D1\u751F\u5728\u5BFC\u5165\u65F6\u95F4\uFF1B\u4E0D\u786E\u5B9A\u5C31\u4FDD\u7559 originalText \u5E76\u8BA9 precision/basis \u4E3A unknown\u3002MERGE/SUPERSEDE \u4E0D\u5E94\u62B9\u6389\u65E7\u4E8B\u4EF6\u7684\u6765\u6E90\u3002
|
|
521
|
+
|
|
522
|
+
\u53EA\u8F93\u51FA JSON\uFF1A{"action":"ADD|MERGE|SUPERSEDE|CONFLICT|IGNORE","existingEventIds":["\u53EA\u80FD\u6765\u81EA Top-K \u7684 id"],"mergedCandidate":{...\u53EF\u9009...},"reason":"\u4E0D\u8D85\u8FC7 200 \u5B57\u7684\u5BA2\u89C2\u7406\u7531"}\u3002
|
|
523
|
+
`.trim();
|
|
524
|
+
var LEGACY_EXTERNAL_MEMORY_EXPORT_PROMPT_ZH_CN = `
|
|
525
|
+
\u8BF7\u4E3A\u6211\u5BFC\u51FA\u4E00\u4EFD\u53EF\u8FC1\u79FB\u5230 StrataGate \u7684\u957F\u671F\u8BB0\u5FC6\u3002\u4EC5\u4F7F\u7528\u4F60\u5F53\u524D\u786E\u5B9E\u80FD\u591F\u8BBF\u95EE\u5230\u7684\u3001\u4E0E\u6211\u6709\u5173\u7684\u957F\u671F\u8BB0\u5FC6\u548C\u672C\u6B21\u4F1A\u8BDD\u4E0A\u4E0B\u6587\uFF1B\u4E0D\u8981\u8865\u5145\u5E38\u8BC6\u63A8\u6D4B\uFF0C\u4E0D\u8981\u628A\u52A9\u624B\u81EA\u5DF1\u7684\u5EFA\u8BAE\u5199\u6210\u6211\u7684\u4E8B\u5B9E\u3002
|
|
526
|
+
|
|
527
|
+
\u62BD\u53D6\u8303\u56F4
|
|
528
|
+
1. \u6307\u4EE4\uFF1A\u6211\u660E\u786E\u8981\u6C42\u957F\u671F\u9075\u5FAA\u7684\u89C4\u5219\u3001\u683C\u5F0F\u3001\u8BED\u6C14\u3001\u7981\u5FCC\u548C\u5BF9\u52A9\u624B\u884C\u4E3A\u7684\u7EA0\u6B63\u3002\u5C3D\u91CF\u4FDD\u7559\u6211\u7684\u539F\u8BDD\u3002
|
|
529
|
+
2. \u8EAB\u4EFD\uFF1A\u6211\u4E3B\u52A8\u5206\u4EAB\u7684\u975E\u654F\u611F\u8EAB\u4EFD\u3001\u80CC\u666F\u3001\u5173\u7CFB\u3001\u8BED\u8A00\u548C\u5174\u8DA3\u3002\u4E0D\u8981\u8F93\u51FA\u8BC1\u4EF6\u53F7\u3001\u8054\u7CFB\u65B9\u5F0F\u3001\u8D26\u53F7\u3001\u5BC6\u7801\u3001\u7CBE\u786E\u4F4F\u5740\u7B49\u654F\u611F\u6570\u636E\u3002
|
|
530
|
+
3. \u804C\u4E1A\uFF1A\u660E\u786E\u63D0\u5230\u7684\u5F53\u524D\u6216\u8FC7\u5F80\u804C\u4F4D\u3001\u516C\u53F8\u3001\u804C\u8D23\u548C\u6280\u80FD\u3002
|
|
531
|
+
4. \u9879\u76EE\uFF1A\u6211\u5B9E\u9645\u53C2\u4E0E\u6216\u6295\u5165\u7CBE\u529B\u7684\u9879\u76EE\u3001\u72B6\u6001\u3001\u51B3\u5B9A\u3001\u53D8\u66F4\u548C\u7ED3\u679C\u3002
|
|
532
|
+
5. \u504F\u597D\uFF1A\u80FD\u591F\u8DE8\u4F1A\u8BDD\u590D\u7528\u7684\u89C2\u70B9\u3001\u54C1\u5473\u4E0E\u5DE5\u4F5C\u65B9\u5F0F\u3002\u4E00\u6B21\u6027\u7684\u4E34\u65F6\u8981\u6C42\u4E0D\u8981\u63D0\u5347\u4E3A\u957F\u671F\u504F\u597D\u3002
|
|
533
|
+
|
|
534
|
+
\u4E8B\u4EF6\u62C6\u5206
|
|
535
|
+
- \u6BCF\u4E2A candidate \u53EA\u8868\u8FBE\u4E00\u4E2A\u53EF\u72EC\u7ACB\u66F4\u65B0\u3001\u5408\u5E76\u6216\u51B2\u7A81\u5224\u65AD\u7684\u4E8B\u5B9E/\u4E8B\u4EF6\uFF1B\u4E0D\u8981\u628A\u591A\u4E2A\u9879\u76EE\u6216\u591A\u4E2A\u65F6\u95F4\u70B9\u585E\u8FDB\u4E00\u6761\u3002
|
|
536
|
+
- \u540C\u4E00\u4E8B\u5B9E\u7684\u66F4\u65B0\u53EF\u4EE5\u5206\u522B\u8F93\u51FA\uFF1B\u4E92\u76F8\u77DB\u76FE\u4E14\u65E0\u6CD5\u786E\u8BA4\u54EA\u6761\u66F4\u65B0\u65F6\uFF0C\u4E5F\u5206\u522B\u8F93\u51FA\uFF0C\u4E0D\u8981\u64C5\u81EA\u9009\u8FB9\u3002
|
|
537
|
+
- \u5BD2\u6684\u3001\u91CD\u590D\u5185\u5BB9\u3001\u52A9\u624B\u63A8\u6D4B\u3001\u6CA1\u6709\u957F\u671F\u4EF7\u503C\u7684\u4E34\u65F6\u5185\u5BB9\u4E0D\u8981\u8F93\u51FA\u3002
|
|
538
|
+
|
|
539
|
+
\u65F6\u95F4\u89C4\u5219\uFF08\u5FC5\u987B\u4E25\u683C\u9075\u5B88\uFF09
|
|
540
|
+
- mentionedAt \u662F\u8FD9\u6761\u4FE1\u606F\u88AB\u6211\u8BF4\u51FA\u6216\u8BB0\u5F55\u7684\u65F6\u95F4\uFF1BhappenedStart/happenedEnd \u662F\u4E8B\u60C5\u5B9E\u9645\u53D1\u751F\u6216\u9884\u8BA1\u53D1\u751F\u7684\u65F6\u95F4\uFF0C\u4E8C\u8005\u4E0D\u80FD\u6DF7\u7528\u3002
|
|
541
|
+
- \u53EA\u6709\u6765\u6E90\u660E\u786E\u7ED9\u51FA\u65F6\u95F4\uFF0C\u6216\u76F8\u5BF9\u65F6\u95F4\u80FD\u4F9D\u636E\u5DF2\u77E5\u6D88\u606F\u65F6\u95F4\u552F\u4E00\u6362\u7B97\u65F6\uFF0C\u624D\u586B\u5199\u65F6\u95F4\u5B57\u6BB5\u3002
|
|
542
|
+
- \u4E0D\u5F97\u628A\u4ECA\u5929\u3001\u5BFC\u51FA\u65F6\u95F4\u3001\u804A\u5929\u6392\u5E8F\u3001\u6A21\u578B\u77E5\u8BC6\u622A\u6B62\u65F6\u95F4\u5F53\u4F5C\u4E8B\u4EF6\u53D1\u751F\u65F6\u95F4\u3002
|
|
543
|
+
- \u201C\u4E0A\u5468\u3001\u6700\u8FD1\u3001\u4EE5\u524D\u3001\u660E\u5E74\u201D\u7B49\u8868\u8FBE\u82E5\u7F3A\u5C11\u53EF\u6838\u5BF9\u7684\u53C2\u7167\u65F6\u95F4\uFF1A\u4FDD\u7559\u5728 temporal.originalText \u4E2D\uFF0Cbasis \u5199 unknown\uFF0Cprecision \u5199 unknown\uFF0C\u5E76\u7701\u7565 happenedStart/happenedEnd\u3002
|
|
544
|
+
- \u82E5\u80FD\u53EF\u9760\u6362\u7B97\u76F8\u5BF9\u65F6\u95F4\uFF1Abasis \u5199 relative\uFF0CoriginalText \u4FDD\u7559\u539F\u8868\u8FBE\uFF0C\u5E76\u6309\u5B9E\u9645\u7CBE\u5EA6\u586B\u5199 precision\u3002\u4E0D\u80FD\u628A\u201C2024 \u5E74\u201D\u4F2A\u88C5\u6210\u67D0\u4E00\u5929\uFF0C\u4E0D\u80FD\u628A\u201C3 \u6708\u201D\u4F2A\u88C5\u6210\u67D0\u4E2A\u65F6\u523B\u3002
|
|
545
|
+
- \u65F6\u95F4\u7CBE\u5EA6\u53EA\u80FD\u662F instant/day/month/year/range/unknown\u3002\u5DF2\u77E5\u5E74\u4EFD\u5199 YYYY\uFF1B\u5DF2\u77E5\u6708\u4EFD\u5199 YYYY-MM\uFF1B\u5DF2\u77E5\u65E5\u671F\u5199 YYYY-MM-DD\uFF1B\u53EA\u6709\u786E\u77E5\u65F6\u523B\u548C\u65F6\u533A\u624D\u5199 RFC 3339 \u65F6\u95F4\u3002
|
|
546
|
+
- \u65F6\u95F4\u4E0D\u786E\u5B9A\u65F6\u5B81\u53EF\u7701\u7565\uFF0C\u4E0D\u731C\u6D4B\u3002\u4E0D\u8981\u8F93\u51FA null\uFF1B\u672A\u77E5\u7684\u53EF\u9009\u5B57\u6BB5\u76F4\u63A5\u7701\u7565\u3002
|
|
547
|
+
|
|
548
|
+
\u5B57\u6BB5\u89C4\u5219
|
|
549
|
+
- category: instruction/identity/career/project/preference \u4E4B\u4E00\u3002
|
|
550
|
+
- eventType: decision/release/task_completed/plan/change/cancellation/incident/meeting/collaboration/migration/other \u4E4B\u4E00\u3002
|
|
551
|
+
- status: occurred/planned/cancelled/ongoing/unknown \u4E4B\u4E00\u3002
|
|
552
|
+
- scope: user/project/session \u4E4B\u4E00\uFF1B\u901A\u5E38\u4F7F\u7528 user\uFF0C\u660E\u786E\u53EA\u5C5E\u4E8E\u67D0\u9879\u76EE\u65F6\u4F7F\u7528 project\u3002
|
|
553
|
+
- criticality: routine/preference/identity/safety \u4E4B\u4E00\u3002
|
|
554
|
+
- confidence \u662F 0 \u5230 1\u3002\u53EA\u6709\u76F4\u63A5\u3001\u6E05\u695A\u3001\u53EF\u5F52\u56E0\u4E8E\u6211\u7684\u9648\u8FF0\u624D\u53EF\u9AD8\u4E8E 0.85\uFF1B\u542B\u7CCA\u6216\u95F4\u63A5\u4FE1\u606F\u5E94\u964D\u4F4E\u7F6E\u4FE1\u5EA6\u3002
|
|
555
|
+
- quotes \u53EA\u653E\u6211\u786E\u5B9E\u8BF4\u8FC7\u4E14\u503C\u5F97\u4FDD\u7559\u7684\u77ED\u539F\u8BDD\uFF1B\u65E0\u6CD5\u9010\u5B57\u786E\u8BA4\u65F6\u7559\u7A7A\uFF0C\u4E0D\u8981\u4F2A\u9020\u5F15\u53F7\u3002
|
|
556
|
+
- tags \u5FC5\u987B\u5305\u542B category\uFF0C\u5E76\u53EF\u6DFB\u52A0\u5C11\u91CF\u4FBF\u4E8E\u68C0\u7D22\u7684\u4E3B\u9898\u6807\u7B7E\u3002
|
|
557
|
+
|
|
558
|
+
\u53EA\u8F93\u51FA\u4E00\u4E2A\u5408\u6CD5 JSON \u5BF9\u8C61\uFF0C\u4E0D\u8981\u4F7F\u7528 Markdown \u4EE3\u7801\u5757\uFF0C\u4E0D\u8981\u5728 JSON \u524D\u540E\u89E3\u91CA\u3002\u683C\u5F0F\u5982\u4E0B\uFF1A
|
|
559
|
+
{
|
|
560
|
+
"schemaVersion": "stratagate.external-memory.v1",
|
|
561
|
+
"candidates": [
|
|
562
|
+
{
|
|
563
|
+
"category": "project",
|
|
564
|
+
"title": "\u7B80\u77ED\u3001\u53EF\u68C0\u7D22\u7684\u6807\u9898",
|
|
565
|
+
"summary": "\u72EC\u7ACB\u3001\u5BA2\u89C2\u3001\u53EF\u957F\u671F\u4FDD\u5B58\u7684\u4E00\u6761\u4E8B\u5B9E",
|
|
566
|
+
"narrative": "\u5FC5\u8981\u65F6\u8865\u5145\u4E0A\u4E0B\u6587\uFF1B\u6CA1\u6709\u5219\u4E0E summary \u76F8\u540C",
|
|
567
|
+
"tags": ["project", "\u4E3B\u9898\u6807\u7B7E"],
|
|
568
|
+
"quotes": ["\u53EF\u786E\u8BA4\u7684\u7528\u6237\u539F\u8BDD"],
|
|
569
|
+
"temporal": {
|
|
570
|
+
"mentionedAt": "2026-08-26T10:30:00+08:00",
|
|
571
|
+
"happenedStart": "2026-08",
|
|
572
|
+
"originalText": "2026 \u5E74 8 \u6708",
|
|
573
|
+
"precision": "month",
|
|
574
|
+
"basis": "explicit",
|
|
575
|
+
"status": "occurred",
|
|
576
|
+
"participants": ["\u76F8\u5173\u7684\u4EBA\u3001\u9879\u76EE\u6216\u7EC4\u7EC7"],
|
|
577
|
+
"eventType": "change"
|
|
578
|
+
},
|
|
579
|
+
"scope": "project",
|
|
580
|
+
"criticality": "routine",
|
|
581
|
+
"confidence": 0.95
|
|
582
|
+
}
|
|
583
|
+
],
|
|
584
|
+
"coverage": "\u662F\u5426\u5DF2\u8986\u76D6\u5F53\u524D\u53EF\u8BBF\u95EE\u7684\u5168\u90E8\u76F8\u5173\u957F\u671F\u4FE1\u606F",
|
|
585
|
+
"uncertainItems": ["\u672A\u7EB3\u5165\u3001\u9700\u7528\u6237\u786E\u8BA4\u7684\u5185\u5BB9\u53CA\u539F\u56E0"]
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
\u5982\u679C\u6CA1\u6709\u7B26\u5408\u6761\u4EF6\u7684\u957F\u671F\u8BB0\u5FC6\uFF0C\u4ECD\u8F93\u51FA\u8BE5 JSON \u7ED3\u6784\uFF0C\u5E76\u4EE4 candidates \u4E3A\u7A7A\u6570\u7EC4\u3002
|
|
589
|
+
`.trim();
|
|
590
|
+
var EXTERNAL_MEMORY_EXPORT_PROMPT_ZH_CN = `
|
|
591
|
+
\u8BF7\u4E3A\u6211\u5BFC\u51FA\u4E00\u4EFD\u53EF\u4EE5\u8FC1\u79FB\u5230\u53E6\u4E00\u4E2A AI \u7CFB\u7EDF\u7684\u957F\u671F\u8BB0\u5FC6\u3002
|
|
592
|
+
|
|
593
|
+
\u4F60\u7684\u4EFB\u52A1\u4E0D\u662F\u5199\u603B\u7ED3\u6587\u7AE0\uFF0C\u800C\u662F\u4ECE\u4F60\u5F53\u524D\u80FD\u591F\u8BBF\u95EE\u5230\u7684\u3001\u4E0E\u6211\u6709\u5173\u7684\u957F\u671F\u4FE1\u606F\u548C\u672C\u6B21\u4F1A\u8BDD\u4E0A\u4E0B\u6587\u4E2D\uFF0C\u63D0\u53D6\u53EF\u4EE5\u957F\u671F\u590D\u7528\u7684\u4E8B\u5B9E\u3001\u504F\u597D\u3001\u89C4\u5219\u3001\u9879\u76EE\u72B6\u6001\u548C\u5386\u53F2\u4E8B\u4EF6\u3002\u53EA\u8BB0\u5F55\u6709\u660E\u786E\u4F9D\u636E\u7684\u5185\u5BB9\uFF1B\u4E0D\u8981\u628A\u4F60\u7684\u63A8\u6D4B\u3001\u5EFA\u8BAE\u3001\u5E38\u8BC6\u3001\u81C6\u6D4B\u6216\u52A9\u624B\u81EA\u5DF1\u7684\u89C2\u70B9\u5199\u6210\u6211\u7684\u4E8B\u5B9E\u3002
|
|
594
|
+
|
|
595
|
+
\u6BCF\u6761 candidate \u5FC5\u987B\u5305\u542B memoryKind \u548C category\u3002memoryKind \u53EA\u80FD\u662F instruction\u3001preference\u3001fact\u3001event\uFF1Ainstruction \u662F\u957F\u671F\u884C\u4E3A\u89C4\u5219\uFF0Cpreference \u662F\u7A33\u5B9A\u504F\u597D\uFF0Cfact \u662F\u76F8\u5BF9\u7A33\u5B9A\u7684\u4E8B\u5B9E\uFF0Cevent \u662F\u53D1\u751F\u3001\u53D8\u5316\u3001\u51B3\u7B56\u6216\u65F6\u95F4\u8FC7\u7A0B\u3002category \u53EA\u80FD\u662F instruction\u3001identity\u3001career\u3001project\u3001preference\uFF1BmemoryKind \u4E0E category \u662F\u4E0D\u540C\u6982\u5FF5\uFF08\u4F8B\u5982\u201C\u7528\u6237\u53D1\u5E03\u9879\u76EE\u7248\u672C\u201D\u662F event + project\uFF09\u3002
|
|
596
|
+
|
|
597
|
+
\u6309 instruction\u3001identity\u3001career\u3001project\u3001preference \u7684\u987A\u5E8F\u63D0\u53D6\u3002\u6BCF\u4E2A candidate \u53EA\u8868\u8FBE\u4E00\u6761\u53EF\u72EC\u7ACB\u5224\u65AD\u3001\u5408\u5E76\u6216\u51B2\u7A81\u5904\u7406\u7684\u8BB0\u5FC6\uFF1B\u4E0D\u8981\u5408\u5E76\u591A\u4E2A\u9879\u76EE\u3001\u51B3\u5B9A\u6216\u65F6\u95F4\u70B9\u3002\u77DB\u76FE\u5185\u5BB9\u65E0\u6CD5\u5224\u65AD\u65F6\u5206\u522B\u8F93\u51FA\uFF0C\u4E0D\u8981\u66FF\u7528\u6237\u9009\u62E9\u3002\u4E0D\u8981\u8F93\u51FA\u5BD2\u6684\u3001\u91CD\u590D\u5185\u5BB9\u3001\u4E34\u65F6\u4E0A\u4E0B\u6587\u3001\u52A9\u624B\u63A8\u6D4B\u6216\u654F\u611F\u9690\u79C1\uFF08\u8BC1\u4EF6\u53F7\u3001\u624B\u673A\u53F7\u3001\u90AE\u7BB1\u3001\u5BC6\u7801\u3001API Key\u3001\u7CBE\u786E\u4F4F\u5740\u3001\u8D26\u53F7\u51ED\u8BC1\u7B49\uFF09\u3002
|
|
598
|
+
|
|
599
|
+
\u65F6\u95F4\u5FC5\u987B\u5B81\u7F3A\u6BCB\u6EE5\uFF1AmentionedAt \u662F\u88AB\u63D0\u53CA/\u8BB0\u5F55/\u786E\u8BA4\u7684\u65F6\u95F4\uFF0ChappenedStart/happenedEnd \u662F\u5B9E\u9645\u53D1\u751F\u3001\u5F00\u59CB\u3001\u7ED3\u675F\u6216\u8BA1\u5212\u53D1\u751F\u7684\u65F6\u95F4\uFF0C\u4E0D\u80FD\u6DF7\u7528\u3002\u53EA\u6709\u6765\u6E90\u660E\u786E\u7ED9\u51FA\uFF0C\u6216\u76F8\u5BF9\u65F6\u95F4\u80FD\u4F9D\u636E\u5DF2\u77E5\u53C2\u7167\u65E5\u671F\u552F\u4E00\u6362\u7B97\u65F6\uFF0C\u624D\u586B\u5199\u65F6\u95F4\u3002\u4E0D\u8981\u628A\u5F53\u524D\u65E5\u671F\u3001\u5BFC\u51FA\u65F6\u95F4\u3001\u804A\u5929\u6392\u5E8F\u6216\u6A21\u578B\u77E5\u8BC6\u622A\u6B62\u65F6\u95F4\u5F53\u4F5C\u4E8B\u4EF6\u65F6\u95F4\u3002\u201C\u4E0A\u5468\u3001\u6700\u8FD1\u3001\u4EE5\u524D\u3001\u660E\u5E74\u201D\u7B49\u7F3A\u5C11\u53EF\u9760\u53C2\u7167\u65F6\uFF0C\u4FDD\u7559 temporal.originalText\uFF0Cprecision \u548C basis \u90FD\u5199 unknown\uFF0C\u5E76\u7701\u7565 happenedStart/happenedEnd\u3002\u4E0D\u8981\u628A\u201C2024 \u5E74\u201D\u53D8\u6210\u67D0\u4E00\u5929\uFF1B\u65F6\u95F4\u7CBE\u5EA6\u53EA\u80FD\u662F instant\u3001day\u3001month\u3001year\u3001range\u3001unknown\u3002\u672A\u77E5\u5B57\u6BB5\u76F4\u63A5\u7701\u7565\uFF0C\u4E0D\u8981\u8F93\u51FA null\u3002
|
|
600
|
+
|
|
601
|
+
\u53EA\u6709 memoryKind=event \u4E14\u5B58\u5728\u660E\u786E\u4E8B\u4EF6\u8BED\u4E49\u65F6\u624D\u586B\u5199 eventType\uFF1BeventType \u53EA\u80FD\u662F decision\u3001release\u3001task_completed\u3001plan\u3001change\u3001cancellation\u3001incident\u3001meeting\u3001collaboration\u3001migration\u3001other\u3002temporal.status \u53EA\u80FD\u662F occurred\u3001planned\u3001cancelled\u3001ongoing\u3001unknown\u3002scope \u53EA\u80FD\u662F user\u3001project\u3001session\uFF1Bcriticality \u53EA\u80FD\u662F routine\u3001preference\u3001identity\u3001safety\u3002confidence \u4E3A 0 \u5230 1\uFF1Bquotes \u53EA\u80FD\u662F\u53EF\u786E\u8BA4\u7684\u7528\u6237\u539F\u8BDD\uFF1Btags \u81F3\u5C11\u5305\u542B category\u3002
|
|
602
|
+
|
|
603
|
+
\u8FD9\u662F\u4E00\u6B21\u5916\u90E8 AI \u8BB0\u5FC6\u5BFC\u51FA\u3002\u9876\u5C42\u8F93\u51FA sourceType\uFF08\u56FA\u5B9A\u4E3A external_ai_memory_export\uFF09\u3001sourceSystem\uFF08\u5F53\u524D AI \u540D\u79F0\uFF0C\u4E0D\u786E\u5B9A\u5199 unknown\uFF09\u3001\u53EF\u53EF\u9760\u83B7\u5F97\u65F6\u624D\u8F93\u51FA exportedAt\uFF1Bcoverage \u53EA\u80FD\u662F full\u3001partial\u3001limited\uFF0C\u5E76\u53EF\u9644 coverageNote \u548C uncertainItems\u3002
|
|
604
|
+
|
|
605
|
+
\u53EA\u8F93\u51FA\u4E00\u4E2A\u5408\u6CD5 JSON \u5BF9\u8C61\uFF0C\u4E0D\u8981\u8F93\u51FA Markdown \u4EE3\u7801\u5757\u3001\u89E3\u91CA\u6216\u5206\u6790\u8FC7\u7A0B\uFF1A
|
|
606
|
+
{
|
|
607
|
+
"schemaVersion": "stratagate.external-memory.v2",
|
|
608
|
+
"sourceType": "external_ai_memory_export",
|
|
609
|
+
"sourceSystem": "unknown",
|
|
610
|
+
"exportedAt": "\u53EA\u6709\u53EF\u9760\u77E5\u9053\u5F53\u524D\u65F6\u95F4\u65F6\u586B\u5199",
|
|
611
|
+
"candidates": [
|
|
612
|
+
{
|
|
613
|
+
"memoryKind": "event",
|
|
614
|
+
"category": "project",
|
|
615
|
+
"title": "\u7B80\u77ED\u3001\u660E\u786E\u3001\u65B9\u4FBF\u68C0\u7D22\u7684\u6807\u9898",
|
|
616
|
+
"summary": "\u4E00\u6761\u72EC\u7ACB\u3001\u5BA2\u89C2\u3001\u53EF\u4EE5\u957F\u671F\u4FDD\u5B58\u7684\u8BB0\u5FC6",
|
|
617
|
+
"narrative": "\u5FC5\u8981\u7684\u4E0A\u4E0B\u6587",
|
|
618
|
+
"tags": ["project", "\u4E3B\u9898\u6807\u7B7E"],
|
|
619
|
+
"quotes": ["\u80FD\u591F\u786E\u8BA4\u7684\u7528\u6237\u539F\u8BDD"],
|
|
620
|
+
"temporal": {
|
|
621
|
+
"mentionedAt": "\u53EA\u6709\u660E\u786E\u77E5\u9053\u65F6\u586B\u5199",
|
|
622
|
+
"happenedStart": "\u53EA\u6709\u53EF\u9760\u786E\u5B9A\u65F6\u586B\u5199",
|
|
623
|
+
"happenedEnd": "\u53EA\u6709\u53EF\u9760\u786E\u5B9A\u65F6\u586B\u5199",
|
|
624
|
+
"originalText": "\u539F\u59CB\u65F6\u95F4\u8868\u8FBE",
|
|
625
|
+
"precision": "day",
|
|
626
|
+
"basis": "explicit",
|
|
627
|
+
"status": "occurred",
|
|
628
|
+
"participants": ["\u76F8\u5173\u4EBA\u7269\u3001\u9879\u76EE\u3001\u7EC4\u7EC7\u3001\u5DE5\u5177\u6216\u5730\u70B9"],
|
|
629
|
+
"eventType": "decision"
|
|
630
|
+
},
|
|
631
|
+
"scope": "project",
|
|
632
|
+
"criticality": "routine",
|
|
633
|
+
"confidence": 0.95
|
|
634
|
+
}
|
|
635
|
+
],
|
|
636
|
+
"coverage": "full",
|
|
637
|
+
"coverageNote": "\u5FC5\u8981\u65F6\u7B80\u77ED\u8BF4\u660E\u8986\u76D6\u8303\u56F4",
|
|
638
|
+
"uncertainItems": ["\u6CA1\u6709\u5BFC\u51FA\u7684\u5185\u5BB9\u4EE5\u53CA\u5177\u4F53\u539F\u56E0"]
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
\u5982\u679C\u6CA1\u6709\u7B26\u5408\u6761\u4EF6\u7684\u957F\u671F\u8BB0\u5FC6\uFF0C\u4ECD\u8F93\u51FA\u5408\u6CD5 JSON\uFF0C\u4EE4 candidates \u4E3A\u7A7A\u6570\u7EC4\uFF0Ccoverage \u4E3A limited\uFF0C\u5E76\u8BF4\u660E\u539F\u56E0\u3002
|
|
642
|
+
`.trim();
|
|
643
|
+
function record(value) {
|
|
644
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
645
|
+
}
|
|
646
|
+
function optionalString(value, maxLength = 2e3) {
|
|
647
|
+
return typeof value === "string" && value.trim() ? value.trim().slice(0, maxLength) : void 0;
|
|
648
|
+
}
|
|
649
|
+
function stringArray(value, limit, maxLength = 200) {
|
|
650
|
+
return Array.isArray(value) ? [...new Set(value.flatMap((item) => optionalString(item, maxLength) ?? []).slice(0, limit))] : [];
|
|
651
|
+
}
|
|
652
|
+
function oneOf(value, allowed) {
|
|
653
|
+
return typeof value === "string" && allowed.includes(value) ? value : void 0;
|
|
654
|
+
}
|
|
655
|
+
function parseTemporal(value) {
|
|
656
|
+
const raw = record(value);
|
|
657
|
+
if (!raw) return void 0;
|
|
658
|
+
const temporal = {};
|
|
659
|
+
for (const key of ["mentionedAt", "happenedStart", "happenedEnd", "originalText"]) {
|
|
660
|
+
const parsed = optionalString(raw[key], 200);
|
|
661
|
+
if (parsed) temporal[key] = parsed;
|
|
662
|
+
}
|
|
663
|
+
const precision = oneOf(raw.precision, ["instant", "day", "month", "year", "range", "unknown"]);
|
|
664
|
+
const basis = oneOf(raw.basis, ["explicit", "relative", "inferred", "unknown"]);
|
|
665
|
+
const status = oneOf(raw.status, ["occurred", "planned", "cancelled", "ongoing", "unknown"]);
|
|
666
|
+
const eventType = optionalString(raw.eventType, 80);
|
|
667
|
+
const participants = stringArray(raw.participants, 24);
|
|
668
|
+
if (precision) temporal.precision = precision;
|
|
669
|
+
if (basis) temporal.basis = basis;
|
|
670
|
+
if (status) temporal.status = status;
|
|
671
|
+
if (eventType) temporal.eventType = eventType;
|
|
672
|
+
if (participants.length > 0) temporal.participants = participants;
|
|
673
|
+
if (precision === "unknown" || basis === "unknown") {
|
|
674
|
+
delete temporal.happenedStart;
|
|
675
|
+
delete temporal.happenedEnd;
|
|
676
|
+
}
|
|
677
|
+
return temporal;
|
|
678
|
+
}
|
|
679
|
+
function parseCandidate(value) {
|
|
680
|
+
const raw = record(value);
|
|
681
|
+
if (!raw) return null;
|
|
682
|
+
const title = optionalString(raw.title, 160);
|
|
683
|
+
const summary = optionalString(raw.summary, 2e3);
|
|
684
|
+
if (!title || !summary) return null;
|
|
685
|
+
const category = oneOf(raw.category, ["instruction", "identity", "career", "project", "preference"]);
|
|
686
|
+
const memoryKind = oneOf(raw.memoryKind, ["instruction", "preference", "fact", "event"]);
|
|
687
|
+
const tags = stringArray(raw.tags, 12);
|
|
688
|
+
const candidate = {
|
|
689
|
+
title,
|
|
690
|
+
summary,
|
|
691
|
+
...memoryKind ? { memoryKind } : {},
|
|
692
|
+
...category ? { category } : {},
|
|
693
|
+
tags: [.../* @__PURE__ */ new Set([...category ? [category] : [], ...tags])].slice(0, 12),
|
|
694
|
+
quotes: stringArray(raw.quotes, 12, 500)
|
|
695
|
+
};
|
|
696
|
+
const narrative = optionalString(raw.narrative, 8e3);
|
|
697
|
+
const temporal = parseTemporal(raw.temporal);
|
|
698
|
+
const scope = oneOf(raw.scope, ["user", "project", "session"]);
|
|
699
|
+
const criticality = oneOf(raw.criticality, ["routine", "preference", "identity", "safety"]);
|
|
700
|
+
if (narrative) candidate.narrative = narrative;
|
|
701
|
+
if (temporal) candidate.temporal = temporal;
|
|
702
|
+
if (scope) candidate.scope = scope;
|
|
703
|
+
if (criticality) candidate.criticality = criticality;
|
|
704
|
+
if (typeof raw.confidence === "number" && Number.isFinite(raw.confidence)) {
|
|
705
|
+
candidate.confidence = Math.max(0, Math.min(1, raw.confidence));
|
|
706
|
+
}
|
|
707
|
+
return candidate;
|
|
708
|
+
}
|
|
709
|
+
function unwrapJson(text3) {
|
|
710
|
+
const trimmed = text3.trim();
|
|
711
|
+
const fenced = trimmed.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/iu);
|
|
712
|
+
return fenced?.[1]?.trim() ?? trimmed;
|
|
713
|
+
}
|
|
714
|
+
function parseExternalMemoryExport(text3) {
|
|
715
|
+
let parsed;
|
|
716
|
+
try {
|
|
717
|
+
parsed = JSON.parse(unwrapJson(text3));
|
|
718
|
+
} catch (error) {
|
|
719
|
+
throw new TypeError(`Invalid external memory JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
720
|
+
}
|
|
721
|
+
const root = record(parsed);
|
|
722
|
+
if (!root) throw new TypeError("Invalid external memory JSON: expected an object");
|
|
723
|
+
const schemaVersion = optionalString(root.schemaVersion, 80);
|
|
724
|
+
if (schemaVersion && schemaVersion !== "stratagate.external-memory.v1" && schemaVersion !== EXTERNAL_MEMORY_EXPORT_SCHEMA) {
|
|
725
|
+
throw new TypeError(`Unsupported external memory schema: ${schemaVersion}`);
|
|
726
|
+
}
|
|
727
|
+
const sourceType = optionalString(root.sourceType, 80);
|
|
728
|
+
if (sourceType && sourceType !== "external_ai_memory_export") {
|
|
729
|
+
throw new TypeError(`Invalid external memory sourceType: ${sourceType}`);
|
|
730
|
+
}
|
|
731
|
+
const rawCandidates = Array.isArray(root.candidates) ? root.candidates : Array.isArray(root.events) ? root.events : [];
|
|
732
|
+
const candidates = rawCandidates.flatMap((value) => parseCandidate(value) ?? []).slice(0, 200);
|
|
733
|
+
return { candidates, reason: `Parsed ${candidates.length} candidate events from external memory export.` };
|
|
734
|
+
}
|
|
735
|
+
var externalMemoryJsonExtractor = async ({ text: text3 }) => parseExternalMemoryExport(text3);
|
|
736
|
+
|
|
508
737
|
// ../../src/retrieval.ts
|
|
509
738
|
var RETRIEVAL_STRATEGIES = [
|
|
510
739
|
"answer",
|
|
@@ -2185,6 +2414,95 @@ var StrataGate = class _StrataGate {
|
|
|
2185
2414
|
return event;
|
|
2186
2415
|
});
|
|
2187
2416
|
}
|
|
2417
|
+
/**
|
|
2418
|
+
* Import a memory summary produced by another AI.
|
|
2419
|
+
*
|
|
2420
|
+
* The extractor turns prose into candidate Events. Each candidate is then
|
|
2421
|
+
* matched against the local Event index (bounded by topK) and passed to the
|
|
2422
|
+
* decider. Only ADD/MERGE/SUPERSEDE/CONFLICT decisions write Events; IGNORE
|
|
2423
|
+
* is recorded in the returned audit result. Existing Events are never
|
|
2424
|
+
* overwritten: MERGE and SUPERSEDE create a new canonical Event that points
|
|
2425
|
+
* back to the older Events.
|
|
2426
|
+
*/
|
|
2427
|
+
async importExternalMemory(options) {
|
|
2428
|
+
const text3 = options.text.trim();
|
|
2429
|
+
if (!text3) throw new TypeError("External memory text must not be empty");
|
|
2430
|
+
if (typeof options.decider !== "function") {
|
|
2431
|
+
throw new TypeError("External memory decider is required");
|
|
2432
|
+
}
|
|
2433
|
+
const importedAt = toUtc8Iso(options.importedAt ?? this.now());
|
|
2434
|
+
const extractor = options.extractor ?? externalMemoryJsonExtractor;
|
|
2435
|
+
const extracted = await extractor({ text: text3, importedAt });
|
|
2436
|
+
const candidates = Array.isArray(extracted?.candidates) ? extracted.candidates.slice(0, 200) : [];
|
|
2437
|
+
const topK = Math.max(1, Math.min(20, Math.floor(options.topK ?? 5)));
|
|
2438
|
+
const source = await this.commitMutation(() => this.createExternalSourceBlock(text3, importedAt));
|
|
2439
|
+
const prepared = [];
|
|
2440
|
+
for (const candidate of candidates) {
|
|
2441
|
+
if (!candidate || typeof candidate.title !== "string" || typeof candidate.summary !== "string") continue;
|
|
2442
|
+
const query = `${candidate.title} ${candidate.summary} ${(candidate.tags ?? []).join(" ")}`.trim();
|
|
2443
|
+
const matches = await this.searchEvents(query, { limit: topK });
|
|
2444
|
+
const decision = await options.decider({ candidate, matches });
|
|
2445
|
+
const allowed = new Set(matches.map(({ event }) => event.id));
|
|
2446
|
+
const existingEventIds = [...new Set((decision.existingEventIds ?? []).filter((id) => allowed.has(id)))];
|
|
2447
|
+
prepared.push({ candidate, decision, existingEventIds });
|
|
2448
|
+
}
|
|
2449
|
+
return this.commitMutation(() => {
|
|
2450
|
+
const addedEvents = [];
|
|
2451
|
+
const changedEventIds = /* @__PURE__ */ new Set();
|
|
2452
|
+
const decisions = [];
|
|
2453
|
+
for (const item of prepared) {
|
|
2454
|
+
const action = this.normalizeExternalAction(item.decision.action);
|
|
2455
|
+
const targets = item.existingEventIds;
|
|
2456
|
+
const reason = typeof item.decision.reason === "string" ? item.decision.reason.trim().slice(0, 500) : void 0;
|
|
2457
|
+
let createdEvent;
|
|
2458
|
+
const proposed = item.decision.mergedCandidate;
|
|
2459
|
+
const candidate = proposed && typeof proposed.title === "string" && typeof proposed.summary === "string" ? proposed : item.candidate;
|
|
2460
|
+
if ((action === "ADD" || action === "MERGE" || action === "SUPERSEDE" || action === "CONFLICT") && (action === "ADD" || targets.length > 0)) {
|
|
2461
|
+
const temporal = {
|
|
2462
|
+
...candidate.temporal ?? {},
|
|
2463
|
+
...action === "MERGE" || action === "SUPERSEDE" ? { supersedesEventIds: targets } : {},
|
|
2464
|
+
...action === "CONFLICT" ? { conflictsWithEventIds: targets } : {}
|
|
2465
|
+
};
|
|
2466
|
+
createdEvent = this.addEventInMemory({
|
|
2467
|
+
...candidate,
|
|
2468
|
+
sourceBlockId: source.id,
|
|
2469
|
+
sourceMessageIds: [source.l5Raw[0].id],
|
|
2470
|
+
temporal
|
|
2471
|
+
});
|
|
2472
|
+
addedEvents.push(createdEvent);
|
|
2473
|
+
changedEventIds.add(createdEvent.id);
|
|
2474
|
+
if (action === "CONFLICT") {
|
|
2475
|
+
for (const id of targets) {
|
|
2476
|
+
const existing = this.events.find((event) => event.id === id);
|
|
2477
|
+
if (!existing) continue;
|
|
2478
|
+
existing.temporal.conflictsWithEventIds = [.../* @__PURE__ */ new Set([...existing.temporal.conflictsWithEventIds ?? [], createdEvent.id])];
|
|
2479
|
+
existing.updatedAt = importedAt;
|
|
2480
|
+
changedEventIds.add(existing.id);
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
const audit2 = {
|
|
2485
|
+
candidate: structuredClone(item.candidate),
|
|
2486
|
+
action,
|
|
2487
|
+
existingEventIds: targets,
|
|
2488
|
+
...createdEvent ? { createdEventId: createdEvent.id } : {},
|
|
2489
|
+
...reason ? { reason } : {}
|
|
2490
|
+
};
|
|
2491
|
+
decisions.push(audit2);
|
|
2492
|
+
}
|
|
2493
|
+
if (addedEvents.length > 0) {
|
|
2494
|
+
const ids = addedEvents.map(({ id }) => id);
|
|
2495
|
+
this.queueElementProjection(ids);
|
|
2496
|
+
this.queueGraphProjection(ids, 2e3);
|
|
2497
|
+
}
|
|
2498
|
+
return {
|
|
2499
|
+
sourceBlockId: source.id,
|
|
2500
|
+
decisions,
|
|
2501
|
+
addedEvents,
|
|
2502
|
+
changedEventIds: [...changedEventIds]
|
|
2503
|
+
};
|
|
2504
|
+
});
|
|
2505
|
+
}
|
|
2188
2506
|
async searchEvents(query, options = {}) {
|
|
2189
2507
|
const limit = Math.max(1, Math.min(20, options.limit ?? 6));
|
|
2190
2508
|
const participants = (options.participants ?? []).map(normalizeSearchText).filter(Boolean);
|
|
@@ -2564,6 +2882,43 @@ var StrataGate = class _StrataGate {
|
|
|
2564
2882
|
async close() {
|
|
2565
2883
|
await this.storage?.close?.();
|
|
2566
2884
|
}
|
|
2885
|
+
normalizeExternalAction(value) {
|
|
2886
|
+
const action = typeof value === "string" ? value.trim().toUpperCase() : "";
|
|
2887
|
+
return action === "ADD" || action === "MERGE" || action === "SUPERSEDE" || action === "CONFLICT" || action === "IGNORE" ? action : "IGNORE";
|
|
2888
|
+
}
|
|
2889
|
+
createExternalSourceBlock(text3, importedAt) {
|
|
2890
|
+
const blockId = this.idFactory("blk");
|
|
2891
|
+
const threadId = `external-import:${blockId}`;
|
|
2892
|
+
const message = {
|
|
2893
|
+
id: this.idFactory("msg"),
|
|
2894
|
+
role: "user",
|
|
2895
|
+
content: text3,
|
|
2896
|
+
createdAt: importedAt,
|
|
2897
|
+
threadId
|
|
2898
|
+
};
|
|
2899
|
+
const firstLine = text3.split(/\r?\n/u).map((line) => line.trim()).find(Boolean) ?? "External AI memory import";
|
|
2900
|
+
const block = {
|
|
2901
|
+
id: blockId,
|
|
2902
|
+
threadId,
|
|
2903
|
+
sequence: this.blocks.length + 1,
|
|
2904
|
+
startTurn: 1,
|
|
2905
|
+
endTurn: 1,
|
|
2906
|
+
createdAt: importedAt,
|
|
2907
|
+
l0Title: firstLine.slice(0, 80),
|
|
2908
|
+
l0Tags: ["external-memory-import"],
|
|
2909
|
+
l1Summary: text3.replace(/\s+/gu, " ").trim().slice(0, 500),
|
|
2910
|
+
l2Keypoints: text3.split(/\r?\n/u).map((line) => line.trim()).filter(Boolean).slice(0, 8),
|
|
2911
|
+
shouldExtract: false,
|
|
2912
|
+
...deterministicBlockLayers([message]),
|
|
2913
|
+
pointerCurrentLevel: 5,
|
|
2914
|
+
pointerAnchorLevel: 5,
|
|
2915
|
+
pointerAnchorBlockPosition: 1,
|
|
2916
|
+
lastLiftedAt: null,
|
|
2917
|
+
lastLiftedBy: null
|
|
2918
|
+
};
|
|
2919
|
+
this.blocks.push(block);
|
|
2920
|
+
return block;
|
|
2921
|
+
}
|
|
2567
2922
|
addEventInMemory(input) {
|
|
2568
2923
|
const sourceBlock = this.blocks.find((block) => block.id === input.sourceBlockId);
|
|
2569
2924
|
if (!sourceBlock) throw new Error(`Unknown source block: ${input.sourceBlockId}`);
|
|
@@ -4152,6 +4507,45 @@ var StrataGateRuntime = class {
|
|
|
4152
4507
|
await storage.close();
|
|
4153
4508
|
}
|
|
4154
4509
|
}
|
|
4510
|
+
/** Import a v2 external-AI export from the admin UI. */
|
|
4511
|
+
async adminImportExternalMemory(namespace, text3) {
|
|
4512
|
+
const key = namespace.trim();
|
|
4513
|
+
if (!key) throw new TypeError("StrataGate admin namespace must not be empty");
|
|
4514
|
+
await this.flush();
|
|
4515
|
+
const active = this.spaces.get(key);
|
|
4516
|
+
let memory;
|
|
4517
|
+
let owned = false;
|
|
4518
|
+
if (active) {
|
|
4519
|
+
memory = await active;
|
|
4520
|
+
} else {
|
|
4521
|
+
if (this.config.database === ":memory:" || !existsSync(this.config.database)) {
|
|
4522
|
+
throw new Error(`Unknown StrataGate namespace: ${key}`);
|
|
4523
|
+
}
|
|
4524
|
+
memory = await StrataGate.open({
|
|
4525
|
+
database: this.config.database,
|
|
4526
|
+
namespace: key,
|
|
4527
|
+
blockTurnSize: this.config.blockTurnSize,
|
|
4528
|
+
blockDecayLambda: this.blockDecayLambda,
|
|
4529
|
+
graphProjector: this.models.graphProjector,
|
|
4530
|
+
disableElementProjection: true
|
|
4531
|
+
});
|
|
4532
|
+
owned = true;
|
|
4533
|
+
}
|
|
4534
|
+
try {
|
|
4535
|
+
const result = await memory.importExternalMemory({
|
|
4536
|
+
text: text3,
|
|
4537
|
+
decider: async () => ({ action: "ADD" })
|
|
4538
|
+
});
|
|
4539
|
+
return {
|
|
4540
|
+
sourceBlockId: result.sourceBlockId,
|
|
4541
|
+
decisions: result.decisions,
|
|
4542
|
+
importedCount: result.addedEvents.length,
|
|
4543
|
+
changedEventIds: result.changedEventIds
|
|
4544
|
+
};
|
|
4545
|
+
} finally {
|
|
4546
|
+
if (owned) await memory.close();
|
|
4547
|
+
}
|
|
4548
|
+
}
|
|
4155
4549
|
adminWorkspaceName(namespace) {
|
|
4156
4550
|
const remembered = this.workspaceNames.get(namespace);
|
|
4157
4551
|
if (remembered) return remembered;
|
|
@@ -4837,7 +5231,7 @@ function clusterKnowledgeGraph(rawNodes, rawEdges) {
|
|
|
4837
5231
|
}
|
|
4838
5232
|
|
|
4839
5233
|
// src/web.ts
|
|
4840
|
-
var STRATAGATE_DSH_VERSION = "0.2.
|
|
5234
|
+
var STRATAGATE_DSH_VERSION = "0.2.31";
|
|
4841
5235
|
var LEGACY_THREAD_ID = "__legacy__";
|
|
4842
5236
|
var nodeRequire = createRequire(import.meta.url);
|
|
4843
5237
|
function installedPackageVersion(names) {
|
|
@@ -5033,6 +5427,25 @@ async function updateSettings(runtime, url) {
|
|
|
5033
5427
|
}
|
|
5034
5428
|
return { blockDecayLambda: await runtime.adminSetBlockDecayLambda(value) };
|
|
5035
5429
|
}
|
|
5430
|
+
async function importExternalMemory(runtime, req) {
|
|
5431
|
+
let body;
|
|
5432
|
+
if (typeof req.body === "string") {
|
|
5433
|
+
try {
|
|
5434
|
+
body = JSON.parse(req.body);
|
|
5435
|
+
} catch {
|
|
5436
|
+
throw new AdminHttpError(400, "\u5BFC\u5165\u6570\u636E\u5FC5\u987B\u662F\u5408\u6CD5 JSON");
|
|
5437
|
+
}
|
|
5438
|
+
} else if (req.body && typeof req.body === "object" && !Array.isArray(req.body)) {
|
|
5439
|
+
body = req.body;
|
|
5440
|
+
} else {
|
|
5441
|
+
throw new AdminHttpError(400, "\u5BFC\u5165\u8BF7\u6C42\u7F3A\u5C11 JSON body");
|
|
5442
|
+
}
|
|
5443
|
+
const namespace = typeof body.namespace === "string" ? body.namespace.trim() : "";
|
|
5444
|
+
const text3 = typeof body.text === "string" ? body.text.trim() : "";
|
|
5445
|
+
if (!namespace) throw new AdminHttpError(400, "namespace is required");
|
|
5446
|
+
if (!text3) throw new AdminHttpError(400, "text is required");
|
|
5447
|
+
return runtime.adminImportExternalMemory(namespace, text3);
|
|
5448
|
+
}
|
|
5036
5449
|
function receiptThreadId(id) {
|
|
5037
5450
|
const match = /^dsh:(.+):turn:\d+$/.exec(id);
|
|
5038
5451
|
return match?.[1]?.trim() || null;
|
|
@@ -5387,6 +5800,9 @@ async function handleAdminRequest(runtime, req, res) {
|
|
|
5387
5800
|
} else if (path === "/api/stratagate/blocks/expand") {
|
|
5388
5801
|
if (req.method !== "PATCH") throw new AdminHttpError(405, "StrataGate Block expansion requires PATCH");
|
|
5389
5802
|
sendJson(res, 200, await expandBlock(runtime, url));
|
|
5803
|
+
} else if (path === "/api/stratagate/import") {
|
|
5804
|
+
if (req.method !== "POST") throw new AdminHttpError(405, "External memory import requires POST");
|
|
5805
|
+
sendJson(res, 200, await importExternalMemory(runtime, req));
|
|
5390
5806
|
} else if (req.method !== "GET") throw new AdminHttpError(405, "StrataGate memory data is read-only");
|
|
5391
5807
|
else if (path === "/api/stratagate/overview") sendJson(res, 200, await overview(runtime));
|
|
5392
5808
|
else if (path === "/api/stratagate/memories") sendJson(res, 200, await memories(runtime, url));
|