omnius 1.0.40 → 1.0.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2529 -308
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -16271,8 +16271,8 @@ function tokenizeSkillQuery(value2) {
|
|
|
16271
16271
|
return out;
|
|
16272
16272
|
}
|
|
16273
16273
|
function compactSkillLine(value2, max = 180) {
|
|
16274
|
-
const
|
|
16275
|
-
return
|
|
16274
|
+
const clean5 = value2.replace(/\s+/g, " ").trim();
|
|
16275
|
+
return clean5.length > max ? `${clean5.slice(0, Math.max(0, max - 3)).trimEnd()}...` : clean5;
|
|
16276
16276
|
}
|
|
16277
16277
|
function skillHaystack(skill) {
|
|
16278
16278
|
return [
|
|
@@ -34756,7 +34756,7 @@ var init_key = __esm({
|
|
|
34756
34756
|
* @param {string | Uint8Array} s
|
|
34757
34757
|
* @param {boolean} [clean]
|
|
34758
34758
|
*/
|
|
34759
|
-
constructor(s2,
|
|
34759
|
+
constructor(s2, clean5) {
|
|
34760
34760
|
if (typeof s2 === "string") {
|
|
34761
34761
|
this._buf = fromString2(s2);
|
|
34762
34762
|
} else if (s2 instanceof Uint8Array) {
|
|
@@ -34764,10 +34764,10 @@ var init_key = __esm({
|
|
|
34764
34764
|
} else {
|
|
34765
34765
|
throw new Error("Invalid key, should be String of Uint8Array");
|
|
34766
34766
|
}
|
|
34767
|
-
if (
|
|
34768
|
-
|
|
34767
|
+
if (clean5 == null) {
|
|
34768
|
+
clean5 = true;
|
|
34769
34769
|
}
|
|
34770
|
-
if (
|
|
34770
|
+
if (clean5) {
|
|
34771
34771
|
this.clean();
|
|
34772
34772
|
}
|
|
34773
34773
|
if (this._buf.byteLength === 0 || this._buf[0] !== pathSep) {
|
|
@@ -85036,10 +85036,10 @@ var require_abort = __commonJS({
|
|
|
85036
85036
|
"../node_modules/asynckit/lib/abort.js"(exports, module) {
|
|
85037
85037
|
module.exports = abort;
|
|
85038
85038
|
function abort(state) {
|
|
85039
|
-
Object.keys(state.jobs).forEach(
|
|
85039
|
+
Object.keys(state.jobs).forEach(clean5.bind(state));
|
|
85040
85040
|
state.jobs = {};
|
|
85041
85041
|
}
|
|
85042
|
-
function
|
|
85042
|
+
function clean5(key) {
|
|
85043
85043
|
if (typeof this.jobs[key] == "function") {
|
|
85044
85044
|
this.jobs[key]();
|
|
85045
85045
|
}
|
|
@@ -91562,7 +91562,7 @@ var require_auto = __commonJS({
|
|
|
91562
91562
|
// ../node_modules/acme-client/src/client.js
|
|
91563
91563
|
var require_client = __commonJS({
|
|
91564
91564
|
"../node_modules/acme-client/src/client.js"(exports, module) {
|
|
91565
|
-
var { createHash:
|
|
91565
|
+
var { createHash: createHash28 } = __require("crypto");
|
|
91566
91566
|
var { getPemBodyAsB64u } = require_crypto();
|
|
91567
91567
|
var { log: log22 } = require_logger();
|
|
91568
91568
|
var HttpClient = require_http();
|
|
@@ -91873,14 +91873,14 @@ var require_client = __commonJS({
|
|
|
91873
91873
|
*/
|
|
91874
91874
|
async getChallengeKeyAuthorization(challenge) {
|
|
91875
91875
|
const jwk = this.http.getJwk();
|
|
91876
|
-
const keysum =
|
|
91876
|
+
const keysum = createHash28("sha256").update(JSON.stringify(jwk));
|
|
91877
91877
|
const thumbprint = keysum.digest("base64url");
|
|
91878
91878
|
const result = `${challenge.token}.${thumbprint}`;
|
|
91879
91879
|
if (challenge.type === "http-01") {
|
|
91880
91880
|
return result;
|
|
91881
91881
|
}
|
|
91882
91882
|
if (challenge.type === "dns-01") {
|
|
91883
|
-
return
|
|
91883
|
+
return createHash28("sha256").update(result).digest("base64url");
|
|
91884
91884
|
}
|
|
91885
91885
|
if (challenge.type === "tls-alpn-01") {
|
|
91886
91886
|
return result;
|
|
@@ -234560,7 +234560,7 @@ var require_websocket2 = __commonJS({
|
|
|
234560
234560
|
var http6 = __require("http");
|
|
234561
234561
|
var net5 = __require("net");
|
|
234562
234562
|
var tls2 = __require("tls");
|
|
234563
|
-
var { randomBytes: randomBytes26, createHash:
|
|
234563
|
+
var { randomBytes: randomBytes26, createHash: createHash28 } = __require("crypto");
|
|
234564
234564
|
var { Duplex: Duplex3, Readable } = __require("stream");
|
|
234565
234565
|
var { URL: URL3 } = __require("url");
|
|
234566
234566
|
var PerMessageDeflate3 = require_permessage_deflate2();
|
|
@@ -235220,7 +235220,7 @@ var require_websocket2 = __commonJS({
|
|
|
235220
235220
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
235221
235221
|
return;
|
|
235222
235222
|
}
|
|
235223
|
-
const digest3 =
|
|
235223
|
+
const digest3 = createHash28("sha1").update(key + GUID).digest("base64");
|
|
235224
235224
|
if (res.headers["sec-websocket-accept"] !== digest3) {
|
|
235225
235225
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
235226
235226
|
return;
|
|
@@ -235587,7 +235587,7 @@ var require_websocket_server = __commonJS({
|
|
|
235587
235587
|
var EventEmitter13 = __require("events");
|
|
235588
235588
|
var http6 = __require("http");
|
|
235589
235589
|
var { Duplex: Duplex3 } = __require("stream");
|
|
235590
|
-
var { createHash:
|
|
235590
|
+
var { createHash: createHash28 } = __require("crypto");
|
|
235591
235591
|
var extension3 = require_extension2();
|
|
235592
235592
|
var PerMessageDeflate3 = require_permessage_deflate2();
|
|
235593
235593
|
var subprotocol3 = require_subprotocol();
|
|
@@ -235888,7 +235888,7 @@ var require_websocket_server = __commonJS({
|
|
|
235888
235888
|
);
|
|
235889
235889
|
}
|
|
235890
235890
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
235891
|
-
const digest3 =
|
|
235891
|
+
const digest3 = createHash28("sha1").update(key + GUID).digest("base64");
|
|
235892
235892
|
const headers = [
|
|
235893
235893
|
"HTTP/1.1 101 Switching Protocols",
|
|
235894
235894
|
"Upgrade: websocket",
|
|
@@ -245608,8 +245608,8 @@ var require_pattern = __commonJS({
|
|
|
245608
245608
|
}
|
|
245609
245609
|
exports.endsWithSlashGlobStar = endsWithSlashGlobStar;
|
|
245610
245610
|
function isAffectDepthOfReadingPattern(pattern) {
|
|
245611
|
-
const
|
|
245612
|
-
return endsWithSlashGlobStar(pattern) || isStaticPattern(
|
|
245611
|
+
const basename30 = path11.basename(pattern);
|
|
245612
|
+
return endsWithSlashGlobStar(pattern) || isStaticPattern(basename30);
|
|
245613
245613
|
}
|
|
245614
245614
|
exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern;
|
|
245615
245615
|
function expandPatternsWithBraceExpansion(patterns) {
|
|
@@ -248695,13 +248695,13 @@ Justification: ${justification || "(none provided)"}`,
|
|
|
248695
248695
|
}
|
|
248696
248696
|
const snapshot = JSON.stringify(this.selfState, null, 2);
|
|
248697
248697
|
try {
|
|
248698
|
-
const { createHash:
|
|
248698
|
+
const { createHash: createHash28 } = await import("node:crypto");
|
|
248699
248699
|
const snapshotDir = join30(this.cwd, ".omnius", "identity", "snapshots");
|
|
248700
248700
|
await mkdir6(snapshotDir, { recursive: true });
|
|
248701
248701
|
const version4 = this.selfState.version;
|
|
248702
248702
|
const snapshotPath = join30(snapshotDir, `v${version4}.json`);
|
|
248703
248703
|
await writeFile11(snapshotPath, snapshot, "utf8");
|
|
248704
|
-
const hash =
|
|
248704
|
+
const hash = createHash28("sha256").update(snapshot).digest("hex");
|
|
248705
248705
|
await writeFile11(join30(this.cwd, ".omnius", "identity", "latest-hash.txt"), hash, "utf8");
|
|
248706
248706
|
let ipfsCid = "";
|
|
248707
248707
|
try {
|
|
@@ -248834,8 +248834,8 @@ New: ${newNarrative.slice(0, 200)}...`,
|
|
|
248834
248834
|
}
|
|
248835
248835
|
// ── Helpers ──────────────────────────────────────────────────────────────
|
|
248836
248836
|
createDefaultState() {
|
|
248837
|
-
const { createHash:
|
|
248838
|
-
const machineId =
|
|
248837
|
+
const { createHash: createHash28 } = __require("node:crypto");
|
|
248838
|
+
const machineId = createHash28("sha256").update(this.cwd).digest("hex").slice(0, 12);
|
|
248839
248839
|
return {
|
|
248840
248840
|
self_id: `omnius-${machineId}`,
|
|
248841
248841
|
version: 1,
|
|
@@ -248917,9 +248917,9 @@ New: ${newNarrative.slice(0, 200)}...`,
|
|
|
248917
248917
|
let cid;
|
|
248918
248918
|
if (this.selfState.version > prevVersion) {
|
|
248919
248919
|
try {
|
|
248920
|
-
const { createHash:
|
|
248920
|
+
const { createHash: createHash28 } = await import("node:crypto");
|
|
248921
248921
|
const stateJson = JSON.stringify(this.selfState);
|
|
248922
|
-
const hash =
|
|
248922
|
+
const hash = createHash28("sha256").update(stateJson).digest("hex").slice(0, 32);
|
|
248923
248923
|
const cidsPath = join30(this.cwd, ".omnius", "identity", "cids.json");
|
|
248924
248924
|
const cidsData = { latest: "", hash, version: this.selfState.version };
|
|
248925
248925
|
try {
|
|
@@ -251005,22 +251005,22 @@ async function runProcess2(command, args, options2) {
|
|
|
251005
251005
|
return;
|
|
251006
251006
|
const parts = raw.split(/[\r\n]+/).filter((part) => part.trim());
|
|
251007
251007
|
for (const part of parts.length > 0 ? parts : [raw]) {
|
|
251008
|
-
const
|
|
251009
|
-
if (!
|
|
251008
|
+
const clean5 = cleanProgressText(part);
|
|
251009
|
+
if (!clean5)
|
|
251010
251010
|
continue;
|
|
251011
251011
|
const now = Date.now();
|
|
251012
|
-
const structured = parseStructuredProgress(
|
|
251013
|
-
if (
|
|
251012
|
+
const structured = parseStructuredProgress(clean5);
|
|
251013
|
+
if (clean5 === lastProgress && now - lastProgressAt < 750)
|
|
251014
251014
|
continue;
|
|
251015
|
-
lastProgress =
|
|
251015
|
+
lastProgress = clean5;
|
|
251016
251016
|
lastProgressAt = now;
|
|
251017
251017
|
if (structured) {
|
|
251018
251018
|
options2.onProgress({ ...structured, elapsedMs: now - startedAt2 });
|
|
251019
251019
|
} else {
|
|
251020
251020
|
options2.onProgress({
|
|
251021
251021
|
stage: stream === "stderr" ? "download" : "process",
|
|
251022
|
-
message:
|
|
251023
|
-
percent: parsePercent(
|
|
251022
|
+
message: clean5.length > 220 ? clean5.slice(0, 217) + "..." : clean5,
|
|
251023
|
+
percent: parsePercent(clean5),
|
|
251024
251024
|
elapsedMs: now - startedAt2
|
|
251025
251025
|
});
|
|
251026
251026
|
}
|
|
@@ -251063,10 +251063,10 @@ async function runProcess2(command, args, options2) {
|
|
|
251063
251063
|
});
|
|
251064
251064
|
}
|
|
251065
251065
|
function trimProcessText(text, max = 1800) {
|
|
251066
|
-
const
|
|
251067
|
-
if (
|
|
251068
|
-
return
|
|
251069
|
-
return
|
|
251066
|
+
const clean5 = text.trim();
|
|
251067
|
+
if (clean5.length <= max)
|
|
251068
|
+
return clean5;
|
|
251069
|
+
return clean5.slice(0, max - 20) + "\n... (truncated)";
|
|
251070
251070
|
}
|
|
251071
251071
|
function formatDiffusersFailure(stderrOrStdout) {
|
|
251072
251072
|
const text = trimProcessText(stderrOrStdout);
|
|
@@ -252632,13 +252632,13 @@ async function runProcess3(command, args, options2) {
|
|
|
252632
252632
|
return;
|
|
252633
252633
|
const parts = raw.split(/[\r\n]+/).filter((part) => part.trim());
|
|
252634
252634
|
for (const part of parts.length > 0 ? parts : [raw]) {
|
|
252635
|
-
const
|
|
252636
|
-
if (!
|
|
252635
|
+
const clean5 = cleanProgressText2(part);
|
|
252636
|
+
if (!clean5)
|
|
252637
252637
|
continue;
|
|
252638
|
-
const jsonStart =
|
|
252638
|
+
const jsonStart = clean5.indexOf("{");
|
|
252639
252639
|
if (jsonStart >= 0) {
|
|
252640
252640
|
try {
|
|
252641
|
-
const payload = JSON.parse(
|
|
252641
|
+
const payload = JSON.parse(clean5.slice(jsonStart));
|
|
252642
252642
|
if (payload.omnius_progress && payload.stage && payload.message) {
|
|
252643
252643
|
const rawTotalBytes = typeof payload.totalBytes === "number" ? payload.totalBytes : typeof payload.total_bytes === "number" ? payload.total_bytes : void 0;
|
|
252644
252644
|
const rawDownloadedBytes = typeof payload.downloadedBytes === "number" ? payload.downloadedBytes : typeof payload.downloaded_bytes === "number" ? payload.downloaded_bytes : void 0;
|
|
@@ -252662,10 +252662,10 @@ async function runProcess3(command, args, options2) {
|
|
|
252662
252662
|
}
|
|
252663
252663
|
}
|
|
252664
252664
|
const now = Date.now();
|
|
252665
|
-
if (
|
|
252666
|
-
lastProgress =
|
|
252665
|
+
if (clean5 !== lastProgress || now - lastProgressAt > 1500) {
|
|
252666
|
+
lastProgress = clean5;
|
|
252667
252667
|
lastProgressAt = now;
|
|
252668
|
-
options2.onProgress({ stage: "process", message:
|
|
252668
|
+
options2.onProgress({ stage: "process", message: clean5.slice(0, 180), elapsedMs: now - startedAt2 });
|
|
252669
252669
|
}
|
|
252670
252670
|
}
|
|
252671
252671
|
};
|
|
@@ -252725,10 +252725,10 @@ async function runProcess3(command, args, options2) {
|
|
|
252725
252725
|
});
|
|
252726
252726
|
}
|
|
252727
252727
|
function trimProcessText2(text, max = 1800) {
|
|
252728
|
-
const
|
|
252729
|
-
if (
|
|
252730
|
-
return
|
|
252731
|
-
return
|
|
252728
|
+
const clean5 = text.trim();
|
|
252729
|
+
if (clean5.length <= max)
|
|
252730
|
+
return clean5;
|
|
252731
|
+
return clean5.slice(0, max - 20) + "\n... (truncated)";
|
|
252732
252732
|
}
|
|
252733
252733
|
async function pythonCanImport2(command, code8, repoRoot, env2) {
|
|
252734
252734
|
return (await pythonImportResult(command, code8, repoRoot, env2)).code === 0;
|
|
@@ -265551,7 +265551,7 @@ var require_typescript = __commonJS({
|
|
|
265551
265551
|
commandLineOptionOfCustomType: () => commandLineOptionOfCustomType,
|
|
265552
265552
|
commentPragmas: () => commentPragmas,
|
|
265553
265553
|
commonOptionsWithBuild: () => commonOptionsWithBuild,
|
|
265554
|
-
compact: () =>
|
|
265554
|
+
compact: () => compact2,
|
|
265555
265555
|
compareBooleans: () => compareBooleans,
|
|
265556
265556
|
compareComparableValues: () => compareComparableValues,
|
|
265557
265557
|
compareDataObjects: () => compareDataObjects,
|
|
@@ -268066,7 +268066,7 @@ var require_typescript = __commonJS({
|
|
|
268066
268066
|
}
|
|
268067
268067
|
return true;
|
|
268068
268068
|
}
|
|
268069
|
-
function
|
|
268069
|
+
function compact2(array) {
|
|
268070
268070
|
let result;
|
|
268071
268071
|
if (array !== void 0) {
|
|
268072
268072
|
for (let i2 = 0; i2 < array.length; i2++) {
|
|
@@ -317409,8 +317409,8 @@ ${lanes.join("\n")}
|
|
|
317409
317409
|
}
|
|
317410
317410
|
}
|
|
317411
317411
|
function isUseStrictPrologueDirective(node) {
|
|
317412
|
-
const
|
|
317413
|
-
return
|
|
317412
|
+
const nodeText22 = getSourceTextOfNodeFromSourceFile(file, node.expression);
|
|
317413
|
+
return nodeText22 === '"use strict"' || nodeText22 === "'use strict'";
|
|
317414
317414
|
}
|
|
317415
317415
|
function bindWorker(node) {
|
|
317416
317416
|
switch (node.kind) {
|
|
@@ -350504,20 +350504,20 @@ ${lanes.join("\n")}
|
|
|
350504
350504
|
return isNullableType(type) ? getNonNullableType(type) : type;
|
|
350505
350505
|
}
|
|
350506
350506
|
function reportObjectPossiblyNullOrUndefinedError(node, facts) {
|
|
350507
|
-
const
|
|
350507
|
+
const nodeText22 = isEntityNameExpression(node) ? entityNameToString(node) : void 0;
|
|
350508
350508
|
if (node.kind === 106) {
|
|
350509
350509
|
error2(node, Diagnostics.The_value_0_cannot_be_used_here, "null");
|
|
350510
350510
|
return;
|
|
350511
350511
|
}
|
|
350512
|
-
if (
|
|
350513
|
-
if (isIdentifier(node) &&
|
|
350512
|
+
if (nodeText22 !== void 0 && nodeText22.length < 100) {
|
|
350513
|
+
if (isIdentifier(node) && nodeText22 === "undefined") {
|
|
350514
350514
|
error2(node, Diagnostics.The_value_0_cannot_be_used_here, "undefined");
|
|
350515
350515
|
return;
|
|
350516
350516
|
}
|
|
350517
350517
|
error2(
|
|
350518
350518
|
node,
|
|
350519
350519
|
facts & 16777216 ? facts & 33554432 ? Diagnostics._0_is_possibly_null_or_undefined : Diagnostics._0_is_possibly_undefined : Diagnostics._0_is_possibly_null,
|
|
350520
|
-
|
|
350520
|
+
nodeText22
|
|
350521
350521
|
);
|
|
350522
350522
|
} else {
|
|
350523
350523
|
error2(
|
|
@@ -350535,9 +350535,9 @@ ${lanes.join("\n")}
|
|
|
350535
350535
|
function checkNonNullTypeWithReporter(type, node, reportError) {
|
|
350536
350536
|
if (strictNullChecks && type.flags & 2) {
|
|
350537
350537
|
if (isEntityNameExpression(node)) {
|
|
350538
|
-
const
|
|
350539
|
-
if (
|
|
350540
|
-
error2(node, Diagnostics._0_is_of_type_unknown,
|
|
350538
|
+
const nodeText22 = entityNameToString(node);
|
|
350539
|
+
if (nodeText22.length < 100) {
|
|
350540
|
+
error2(node, Diagnostics._0_is_of_type_unknown, nodeText22);
|
|
350541
350541
|
return errorType;
|
|
350542
350542
|
}
|
|
350543
350543
|
}
|
|
@@ -350563,13 +350563,13 @@ ${lanes.join("\n")}
|
|
|
350563
350563
|
const nonNullType = checkNonNullType(type, node);
|
|
350564
350564
|
if (nonNullType.flags & 16) {
|
|
350565
350565
|
if (isEntityNameExpression(node)) {
|
|
350566
|
-
const
|
|
350567
|
-
if (isIdentifier(node) &&
|
|
350568
|
-
error2(node, Diagnostics.The_value_0_cannot_be_used_here,
|
|
350566
|
+
const nodeText22 = entityNameToString(node);
|
|
350567
|
+
if (isIdentifier(node) && nodeText22 === "undefined") {
|
|
350568
|
+
error2(node, Diagnostics.The_value_0_cannot_be_used_here, nodeText22);
|
|
350569
350569
|
return nonNullType;
|
|
350570
350570
|
}
|
|
350571
|
-
if (
|
|
350572
|
-
error2(node, Diagnostics._0_is_possibly_undefined,
|
|
350571
|
+
if (nodeText22.length < 100) {
|
|
350572
|
+
error2(node, Diagnostics._0_is_possibly_undefined, nodeText22);
|
|
350573
350573
|
return nonNullType;
|
|
350574
350574
|
}
|
|
350575
350575
|
}
|
|
@@ -374137,7 +374137,7 @@ ${lanes.join("\n")}
|
|
|
374137
374137
|
node.operatorToken,
|
|
374138
374138
|
visitNode(node.right, visitor, isExpression)
|
|
374139
374139
|
);
|
|
374140
|
-
const expr = some(pendingExpressions) ? factory2.inlineExpressions(
|
|
374140
|
+
const expr = some(pendingExpressions) ? factory2.inlineExpressions(compact2([...pendingExpressions, node])) : node;
|
|
374141
374141
|
pendingExpressions = savedPendingExpressions;
|
|
374142
374142
|
return expr;
|
|
374143
374143
|
}
|
|
@@ -394406,7 +394406,7 @@ ${lanes.join("\n")}
|
|
|
394406
394406
|
let parameterProperties;
|
|
394407
394407
|
if (ctor) {
|
|
394408
394408
|
const oldDiag2 = getSymbolAccessibilityDiagnostic;
|
|
394409
|
-
parameterProperties =
|
|
394409
|
+
parameterProperties = compact2(flatMap(ctor.parameters, (param) => {
|
|
394410
394410
|
if (!hasSyntacticModifier(
|
|
394411
394411
|
param,
|
|
394412
394412
|
31
|
|
@@ -402392,9 +402392,9 @@ ${lanes.join("\n")}
|
|
|
402392
402392
|
/*ignoreCase*/
|
|
402393
402393
|
false
|
|
402394
402394
|
)) {
|
|
402395
|
-
const
|
|
402396
|
-
if (
|
|
402397
|
-
const name10 = removeSuffix(removePrefix(
|
|
402395
|
+
const basename30 = getBaseFileName(a2.fileName);
|
|
402396
|
+
if (basename30 === "lib.d.ts" || basename30 === "lib.es6.d.ts") return 0;
|
|
402397
|
+
const name10 = removeSuffix(removePrefix(basename30, "lib."), ".d.ts");
|
|
402398
402398
|
const index = libs.indexOf(name10);
|
|
402399
402399
|
if (index !== -1) return index + 1;
|
|
402400
402400
|
}
|
|
@@ -411161,7 +411161,7 @@ ${lanes.join("\n")}
|
|
|
411161
411161
|
startWatching(state, buildOrder);
|
|
411162
411162
|
return isCircularBuildOrder(buildOrder) ? 4 : !buildOrder.some((p2) => state.diagnostics.has(toResolvedConfigFilePath(state, p2))) ? 0 : successfulProjects ? 2 : 1;
|
|
411163
411163
|
}
|
|
411164
|
-
function
|
|
411164
|
+
function clean5(state, project, onlyReferences) {
|
|
411165
411165
|
mark("SolutionBuilder::beforeClean");
|
|
411166
411166
|
const result = cleanWorker(state, project, onlyReferences);
|
|
411167
411167
|
mark("SolutionBuilder::afterClean");
|
|
@@ -411450,7 +411450,7 @@ ${lanes.join("\n")}
|
|
|
411450
411450
|
const state = createSolutionBuilderState(watch, hostOrHostWithWatch, rootNames, options2, baseWatchOptions);
|
|
411451
411451
|
return {
|
|
411452
411452
|
build: (project, cancellationToken, writeFile23, getCustomTransformers) => build(state, project, cancellationToken, writeFile23, getCustomTransformers),
|
|
411453
|
-
clean: (project) =>
|
|
411453
|
+
clean: (project) => clean5(state, project),
|
|
411454
411454
|
buildReferences: (project, cancellationToken, writeFile23, getCustomTransformers) => build(
|
|
411455
411455
|
state,
|
|
411456
411456
|
project,
|
|
@@ -411460,7 +411460,7 @@ ${lanes.join("\n")}
|
|
|
411460
411460
|
/*onlyReferences*/
|
|
411461
411461
|
true
|
|
411462
411462
|
),
|
|
411463
|
-
cleanReferences: (project) =>
|
|
411463
|
+
cleanReferences: (project) => clean5(
|
|
411464
411464
|
state,
|
|
411465
411465
|
project,
|
|
411466
411466
|
/*onlyReferences*/
|
|
@@ -421352,7 +421352,7 @@ interface Symbol {
|
|
|
421352
421352
|
parent = void 0;
|
|
421353
421353
|
emptyChildItemArray = [];
|
|
421354
421354
|
}
|
|
421355
|
-
function
|
|
421355
|
+
function nodeText2(node) {
|
|
421356
421356
|
return cleanText(node.getText(curSourceFile));
|
|
421357
421357
|
}
|
|
421358
421358
|
function navigationBarNodeKind(n2) {
|
|
@@ -421667,7 +421667,7 @@ interface Symbol {
|
|
|
421667
421667
|
const nameToItems = /* @__PURE__ */ new Map();
|
|
421668
421668
|
filterMutate(children2, (child, index) => {
|
|
421669
421669
|
const declName = child.name || getNameOfDeclaration(child.node);
|
|
421670
|
-
const name10 = declName &&
|
|
421670
|
+
const name10 = declName && nodeText2(declName);
|
|
421671
421671
|
if (!name10) {
|
|
421672
421672
|
return true;
|
|
421673
421673
|
}
|
|
@@ -421893,7 +421893,7 @@ interface Symbol {
|
|
|
421893
421893
|
return cleanText(getModuleName(node));
|
|
421894
421894
|
}
|
|
421895
421895
|
if (name10) {
|
|
421896
|
-
const text = isIdentifier(name10) ? name10.text : isElementAccessExpression(name10) ? `[${
|
|
421896
|
+
const text = isIdentifier(name10) ? name10.text : isElementAccessExpression(name10) ? `[${nodeText2(name10.argumentExpression)}]` : nodeText2(name10);
|
|
421897
421897
|
if (text.length > 0) {
|
|
421898
421898
|
return cleanText(text);
|
|
421899
421899
|
}
|
|
@@ -422056,9 +422056,9 @@ interface Symbol {
|
|
|
422056
422056
|
} else if (isVariableDeclaration(parent2)) {
|
|
422057
422057
|
return cleanText(declarationNameToString(parent2.name));
|
|
422058
422058
|
} else if (isBinaryExpression(parent2) && parent2.operatorToken.kind === 64) {
|
|
422059
|
-
return
|
|
422059
|
+
return nodeText2(parent2.left).replace(whiteSpaceRegex, "");
|
|
422060
422060
|
} else if (isPropertyAssignment(parent2)) {
|
|
422061
|
-
return
|
|
422061
|
+
return nodeText2(parent2.name);
|
|
422062
422062
|
} else if (getSyntacticModifierFlags(node) & 2048) {
|
|
422063
422063
|
return "default";
|
|
422064
422064
|
} else if (isClassLike(node)) {
|
|
@@ -431487,7 +431487,7 @@ ${newComment.split("\n").map((c9) => ` * ${c9}`).join("\n")}
|
|
|
431487
431487
|
}
|
|
431488
431488
|
const checker = context2.program.getTypeChecker();
|
|
431489
431489
|
const trackChanges = (cb) => ts_textChanges_exports.ChangeTracker.with(context2, cb);
|
|
431490
|
-
return
|
|
431490
|
+
return compact2([
|
|
431491
431491
|
getDeclarationSiteFix(context2, expression, errorCode, checker, trackChanges),
|
|
431492
431492
|
getUseSiteFix(context2, expression, errorCode, checker, trackChanges)
|
|
431493
431493
|
]);
|
|
@@ -455078,7 +455078,7 @@ ${content}
|
|
|
455078
455078
|
const lastToken = last2(children2);
|
|
455079
455079
|
const separateLastToken = separateTrailingSemicolon && lastToken.kind === 27;
|
|
455080
455080
|
const rightChildren = children2.slice(splitTokenIndex + 1, separateLastToken ? children2.length - 1 : void 0);
|
|
455081
|
-
const result =
|
|
455081
|
+
const result = compact2([
|
|
455082
455082
|
leftChildren.length ? createSyntaxList2(leftChildren) : void 0,
|
|
455083
455083
|
splitToken,
|
|
455084
455084
|
rightChildren.length ? createSyntaxList2(rightChildren) : void 0
|
|
@@ -461802,7 +461802,7 @@ ${options2.prefix}` : "\n" : options2.prefix
|
|
|
461802
461802
|
commandLineOptionOfCustomType: () => commandLineOptionOfCustomType,
|
|
461803
461803
|
commentPragmas: () => commentPragmas,
|
|
461804
461804
|
commonOptionsWithBuild: () => commonOptionsWithBuild,
|
|
461805
|
-
compact: () =>
|
|
461805
|
+
compact: () => compact2,
|
|
461806
461806
|
compareBooleans: () => compareBooleans,
|
|
461807
461807
|
compareComparableValues: () => compareComparableValues,
|
|
461808
461808
|
compareDataObjects: () => compareDataObjects,
|
|
@@ -466320,8 +466320,8 @@ ${options2.prefix}` : "\n" : options2.prefix
|
|
|
466320
466320
|
}
|
|
466321
466321
|
};
|
|
466322
466322
|
for (const file of files) {
|
|
466323
|
-
const
|
|
466324
|
-
if (
|
|
466323
|
+
const basename30 = getBaseFileName(file);
|
|
466324
|
+
if (basename30 === "package.json" || basename30 === "bower.json") {
|
|
466325
466325
|
createProjectWatcher(
|
|
466326
466326
|
file,
|
|
466327
466327
|
"FileWatcher"
|
|
@@ -470005,8 +470005,8 @@ All files are: ${JSON.stringify(names)}`,
|
|
|
470005
470005
|
var _a;
|
|
470006
470006
|
const fileOrDirectoryPath = removeIgnoredPath(this.toPath(fileOrDirectory));
|
|
470007
470007
|
if (!fileOrDirectoryPath) return;
|
|
470008
|
-
const
|
|
470009
|
-
if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (
|
|
470008
|
+
const basename30 = getBaseFileName(fileOrDirectoryPath);
|
|
470009
|
+
if (((_a = result.affectedModuleSpecifierCacheProjects) == null ? void 0 : _a.size) && (basename30 === "package.json" || basename30 === "node_modules")) {
|
|
470010
470010
|
result.affectedModuleSpecifierCacheProjects.forEach((project) => {
|
|
470011
470011
|
var _a2;
|
|
470012
470012
|
(_a2 = project.getModuleSpecifierCache()) == null ? void 0 : _a2.clear();
|
|
@@ -478909,7 +478909,7 @@ var require_path_browserify = __commonJS({
|
|
|
478909
478909
|
if (hasRoot && end === 1) return "//";
|
|
478910
478910
|
return path11.slice(0, end);
|
|
478911
478911
|
},
|
|
478912
|
-
basename: function
|
|
478912
|
+
basename: function basename30(path11, ext) {
|
|
478913
478913
|
if (ext !== void 0 && typeof ext !== "string") throw new TypeError('"ext" argument must be a string');
|
|
478914
478914
|
assertPath(path11);
|
|
478915
478915
|
var start2 = 0;
|
|
@@ -512614,6 +512614,11 @@ var init_visual_memory = __esm({
|
|
|
512614
512614
|
type: "number",
|
|
512615
512615
|
description: "Recognition confidence threshold 0-1 (default: 0.5 for faces, 0.3 for objects)."
|
|
512616
512616
|
},
|
|
512617
|
+
format: {
|
|
512618
|
+
type: "string",
|
|
512619
|
+
enum: ["text", "json"],
|
|
512620
|
+
description: "Return format for identify/recognize results. Use json when another tool or service needs machine-readable matches."
|
|
512621
|
+
},
|
|
512617
512622
|
labels: {
|
|
512618
512623
|
type: "array",
|
|
512619
512624
|
description: "Text labels to score against image (for CLIP 'recognize' or 'describe').",
|
|
@@ -512661,6 +512666,7 @@ var init_visual_memory = __esm({
|
|
|
512661
512666
|
if (!image || !existsSync45(image)) {
|
|
512662
512667
|
return { success: false, output: "", error: "Provide a valid image path.", durationMs: performance.now() - start2 };
|
|
512663
512668
|
}
|
|
512669
|
+
const wantsJson = args["format"] === "json" || args["json"] === true;
|
|
512664
512670
|
const result = await this.runVisionPython(`
|
|
512665
512671
|
import json, sys
|
|
512666
512672
|
from insightface.app import FaceAnalysis
|
|
@@ -512690,6 +512696,10 @@ print(json.dumps({"success": True, "faces": results, "total": len(results)}))
|
|
|
512690
512696
|
`, 6e4);
|
|
512691
512697
|
if (!result.success)
|
|
512692
512698
|
return { success: false, output: "", error: result.error, durationMs: performance.now() - start2 };
|
|
512699
|
+
if (wantsJson) {
|
|
512700
|
+
const payload = JSON.stringify(result);
|
|
512701
|
+
return { success: true, output: payload, llmContent: payload, durationMs: performance.now() - start2 };
|
|
512702
|
+
}
|
|
512693
512703
|
return { success: true, output: `Detected ${result.total} face(s):
|
|
512694
512704
|
${JSON.stringify(result.faces, null, 2)}`, durationMs: performance.now() - start2 };
|
|
512695
512705
|
}
|
|
@@ -512771,6 +512781,7 @@ print(json.dumps({
|
|
|
512771
512781
|
if (!image || !existsSync45(image))
|
|
512772
512782
|
return { success: false, output: "", error: "Provide a valid image path.", durationMs: performance.now() - start2 };
|
|
512773
512783
|
const threshold = args["threshold"] || 0.5;
|
|
512784
|
+
const wantsJson = args["format"] === "json" || args["json"] === true;
|
|
512774
512785
|
const result = await this.runVisionPython(`
|
|
512775
512786
|
import json, sys, os, numpy as np
|
|
512776
512787
|
from insightface.app import FaceAnalysis
|
|
@@ -512838,6 +512849,15 @@ print(json.dumps({"success": True, "faces": results, "total_detected": len(faces
|
|
|
512838
512849
|
`, 6e4);
|
|
512839
512850
|
if (!result.success)
|
|
512840
512851
|
return { success: false, output: "", error: result.error, durationMs: performance.now() - start2 };
|
|
512852
|
+
if (wantsJson) {
|
|
512853
|
+
const payload = JSON.stringify(result);
|
|
512854
|
+
return {
|
|
512855
|
+
success: true,
|
|
512856
|
+
output: payload,
|
|
512857
|
+
llmContent: payload,
|
|
512858
|
+
durationMs: performance.now() - start2
|
|
512859
|
+
};
|
|
512860
|
+
}
|
|
512841
512861
|
const faces = result.faces || [];
|
|
512842
512862
|
if (faces.length === 0) {
|
|
512843
512863
|
return { success: true, output: "No faces detected in image.", durationMs: performance.now() - start2 };
|
|
@@ -512934,6 +512954,7 @@ print(json.dumps({
|
|
|
512934
512954
|
return { success: false, output: "", error: "Provide a valid image path.", durationMs: performance.now() - start2 };
|
|
512935
512955
|
const threshold = args["threshold"] || 0.3;
|
|
512936
512956
|
const extraLabels = args["labels"] || [];
|
|
512957
|
+
const wantsJson = args["format"] === "json" || args["json"] === true;
|
|
512937
512958
|
const result = await this.runVisionPython(`
|
|
512938
512959
|
import json, sys, os, numpy as np
|
|
512939
512960
|
import torch
|
|
@@ -513009,6 +513030,10 @@ print(json.dumps({
|
|
|
513009
513030
|
`, 12e4);
|
|
513010
513031
|
if (!result.success)
|
|
513011
513032
|
return { success: false, output: "", error: result.error, durationMs: performance.now() - start2 };
|
|
513033
|
+
if (wantsJson) {
|
|
513034
|
+
const payload = JSON.stringify(result);
|
|
513035
|
+
return { success: true, output: payload, llmContent: payload, durationMs: performance.now() - start2 };
|
|
513036
|
+
}
|
|
513012
513037
|
const matches = (result.matches || []).filter((m2) => m2.recognized);
|
|
513013
513038
|
const lines = matches.map((m2) => ` ${m2.label}: ${(m2.blended_score * 100).toFixed(0)}% (image=${(m2.image_similarity * 100).toFixed(0)}%, text=${(m2.text_similarity * 100).toFixed(0)}%)`);
|
|
513014
513039
|
let output = matches.length > 0 ? `Recognized ${result.recognized_count} object(s):
|
|
@@ -524884,6 +524909,9 @@ var init_temporalGraph = __esm({
|
|
|
524884
524909
|
nodesByType(nodeType, limit = 100) {
|
|
524885
524910
|
return this.db.prepare("SELECT * FROM kg_nodes WHERE node_type = ? ORDER BY mention_count DESC LIMIT ?").all(nodeType, limit).map((r2) => this.rowToNode(r2));
|
|
524886
524911
|
}
|
|
524912
|
+
allNodes(limit = 1e3) {
|
|
524913
|
+
return this.db.prepare("SELECT * FROM kg_nodes ORDER BY mention_count DESC, last_seen DESC LIMIT ?").all(limit).map((r2) => this.rowToNode(r2));
|
|
524914
|
+
}
|
|
524887
524915
|
/**
|
|
524888
524916
|
* Find code-symbol entity nodes by the inner symbol name. Symbol nodes
|
|
524889
524917
|
* stored by the cross-graph link layer use text `sym:{name}@{path}`;
|
|
@@ -524977,6 +525005,26 @@ var init_temporalGraph = __esm({
|
|
|
524977
525005
|
edge: this.rowToEdge(r2)
|
|
524978
525006
|
}));
|
|
524979
525007
|
}
|
|
525008
|
+
currentEdgesForSourceEpisode(sourceEpisodeId, limit = 200) {
|
|
525009
|
+
return this.db.prepare(`
|
|
525010
|
+
SELECT * FROM kg_edges
|
|
525011
|
+
WHERE source_episode_id = ? AND valid_until IS NULL
|
|
525012
|
+
ORDER BY confidence DESC, valid_from DESC
|
|
525013
|
+
LIMIT ?
|
|
525014
|
+
`).all(sourceEpisodeId, limit).map((r2) => this.rowToEdge(r2));
|
|
525015
|
+
}
|
|
525016
|
+
currentEdgesForSourceEpisodes(sourceEpisodeIds, limit = 1e3) {
|
|
525017
|
+
const ids = [...new Set(sourceEpisodeIds.filter(Boolean))];
|
|
525018
|
+
if (ids.length === 0)
|
|
525019
|
+
return [];
|
|
525020
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
525021
|
+
return this.db.prepare(`
|
|
525022
|
+
SELECT * FROM kg_edges
|
|
525023
|
+
WHERE source_episode_id IN (${placeholders}) AND valid_until IS NULL
|
|
525024
|
+
ORDER BY confidence DESC, valid_from DESC
|
|
525025
|
+
LIMIT ?
|
|
525026
|
+
`).all(...ids, limit).map((r2) => this.rowToEdge(r2));
|
|
525027
|
+
}
|
|
524980
525028
|
// ─── Statistics ──────────────────────────────────────────────────────────
|
|
524981
525029
|
nodeCount() {
|
|
524982
525030
|
return this.db.prepare("SELECT COUNT(*) as n FROM kg_nodes").get().n;
|
|
@@ -525118,6 +525166,7 @@ var init_multimodalIdentity = __esm({
|
|
|
525118
525166
|
const sender = input.sender;
|
|
525119
525167
|
const content = buildEpisodeContent(input);
|
|
525120
525168
|
const metadata = {
|
|
525169
|
+
...input.metadata || {},
|
|
525121
525170
|
mmidVersion: 1,
|
|
525122
525171
|
sourceSurface,
|
|
525123
525172
|
scope,
|
|
@@ -525132,6 +525181,7 @@ var init_multimodalIdentity = __esm({
|
|
|
525132
525181
|
embeddingSpaces: this.embeddingSpaces(input.embeddings)
|
|
525133
525182
|
};
|
|
525134
525183
|
const episodeId = this.episodeStore.insert({
|
|
525184
|
+
sessionId: input.sessionId,
|
|
525135
525185
|
modality,
|
|
525136
525186
|
content,
|
|
525137
525187
|
metadata,
|
|
@@ -525205,6 +525255,7 @@ var init_multimodalIdentity = __esm({
|
|
|
525205
525255
|
if (input.transcript && input.transcript.trim()) {
|
|
525206
525256
|
const transcriptMeta = { ...metadata, sourceEpisodeId: episodeId, transcriptOf: episodeId };
|
|
525207
525257
|
const transcriptEpisodeId = this.episodeStore.insert({
|
|
525258
|
+
sessionId: input.sessionId,
|
|
525208
525259
|
modality: "text",
|
|
525209
525260
|
content: input.transcript,
|
|
525210
525261
|
metadata: transcriptMeta,
|
|
@@ -525380,6 +525431,158 @@ var init_gistCompressor = __esm({
|
|
|
525380
525431
|
}
|
|
525381
525432
|
});
|
|
525382
525433
|
|
|
525434
|
+
// packages/memory/dist/graphWalk.js
|
|
525435
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
525436
|
+
function seededUnit(seed) {
|
|
525437
|
+
const digest3 = createHash12("sha256").update(seed || "graph-walk").digest();
|
|
525438
|
+
const value2 = digest3.readUInt32BE(0);
|
|
525439
|
+
return value2 / 4294967295;
|
|
525440
|
+
}
|
|
525441
|
+
function edgeKey(edge) {
|
|
525442
|
+
return String(edge.id ?? `${edge.srcId}:${edge.dstId}:${edge.relation}:${edge.sourceEpisodeId ?? ""}`);
|
|
525443
|
+
}
|
|
525444
|
+
function recencyScore(timestamp, now) {
|
|
525445
|
+
if (!timestamp || !Number.isFinite(timestamp))
|
|
525446
|
+
return 0;
|
|
525447
|
+
const ageMs = Math.max(0, now - timestamp);
|
|
525448
|
+
return Math.exp(-ageMs / (7 * 24 * 60 * 6e4));
|
|
525449
|
+
}
|
|
525450
|
+
function relationAllowed(edge, options2) {
|
|
525451
|
+
if (options2.allowedRelations?.length && !options2.allowedRelations.includes(edge.relation))
|
|
525452
|
+
return false;
|
|
525453
|
+
if (options2.deniedRelations?.includes(edge.relation))
|
|
525454
|
+
return false;
|
|
525455
|
+
return true;
|
|
525456
|
+
}
|
|
525457
|
+
function selectInnerGraphCandidates(graph, candidates, options2 = {}) {
|
|
525458
|
+
const minDegree = Math.max(1, Math.floor(options2.minDegree ?? 2));
|
|
525459
|
+
const candidateEpisodeIds = [...new Set(candidates.map((candidate) => candidate.episode.id).filter(Boolean))];
|
|
525460
|
+
const candidateScore = new Map(candidates.map((candidate) => [candidate.episode.id, candidate.score ?? 0]));
|
|
525461
|
+
const candidateTimestamp = new Map(candidates.map((candidate) => [candidate.episode.id, candidate.episode.timestamp]));
|
|
525462
|
+
const sourceEdges = graph.currentEdgesForSourceEpisodes(candidateEpisodeIds, Math.max(1e3, candidateEpisodeIds.length * 20));
|
|
525463
|
+
const byNode = /* @__PURE__ */ new Map();
|
|
525464
|
+
for (const edge of sourceEdges) {
|
|
525465
|
+
if (!relationAllowed(edge, options2))
|
|
525466
|
+
continue;
|
|
525467
|
+
const episodeId = edge.sourceEpisodeId;
|
|
525468
|
+
if (!episodeId || !candidateEpisodeIds.includes(episodeId))
|
|
525469
|
+
continue;
|
|
525470
|
+
for (const nodeId of [edge.srcId, edge.dstId]) {
|
|
525471
|
+
const node = graph.getNode(nodeId);
|
|
525472
|
+
if (!node)
|
|
525473
|
+
continue;
|
|
525474
|
+
const entry = byNode.get(nodeId) ?? { node, candidateEpisodeIds: /* @__PURE__ */ new Set(), edges: /* @__PURE__ */ new Map() };
|
|
525475
|
+
entry.candidateEpisodeIds.add(episodeId);
|
|
525476
|
+
entry.edges.set(edgeKey(edge), edge);
|
|
525477
|
+
byNode.set(nodeId, entry);
|
|
525478
|
+
}
|
|
525479
|
+
}
|
|
525480
|
+
const now = Date.now();
|
|
525481
|
+
const results = [];
|
|
525482
|
+
for (const entry of byNode.values()) {
|
|
525483
|
+
const allEdges = graph.currentEdges(entry.node.id).filter((edge) => relationAllowed(edge, options2));
|
|
525484
|
+
const degree = allEdges.length;
|
|
525485
|
+
if (degree < minDegree)
|
|
525486
|
+
continue;
|
|
525487
|
+
const relationDiversity = new Set(allEdges.map((edge) => edge.relation)).size;
|
|
525488
|
+
const sourceEpisodeIds = [...new Set(allEdges.map((edge) => edge.sourceEpisodeId).filter((id) => Boolean(id)))];
|
|
525489
|
+
const selectedEpisodeIds = [...entry.candidateEpisodeIds];
|
|
525490
|
+
const sourceStrength = sourceEpisodeIds.length;
|
|
525491
|
+
const candidateStrength = selectedEpisodeIds.reduce((sum, id) => sum + (candidateScore.get(id) ?? 0), 0);
|
|
525492
|
+
const recency = selectedEpisodeIds.reduce((sum, id) => sum + recencyScore(candidateTimestamp.get(id), now), 0);
|
|
525493
|
+
const confidence2 = allEdges.reduce((sum, edge) => sum + (Number.isFinite(edge.confidence) ? edge.confidence : 0), 0) / Math.max(1, allEdges.length);
|
|
525494
|
+
const score = degree * 1.5 + relationDiversity * 1.2 + sourceStrength * 1.4 + selectedEpisodeIds.length * 1.6 + candidateStrength + recency + confidence2 + Math.log1p(entry.node.mentionCount);
|
|
525495
|
+
results.push({
|
|
525496
|
+
node: entry.node,
|
|
525497
|
+
score,
|
|
525498
|
+
degree,
|
|
525499
|
+
relationDiversity,
|
|
525500
|
+
sourceEpisodeIds,
|
|
525501
|
+
candidateEpisodeIds: selectedEpisodeIds,
|
|
525502
|
+
edges: allEdges
|
|
525503
|
+
});
|
|
525504
|
+
}
|
|
525505
|
+
return results.sort((a2, b) => b.score - a2.score || b.degree - a2.degree || a2.node.text.localeCompare(b.node.text));
|
|
525506
|
+
}
|
|
525507
|
+
function chooseInnerGraphSeed(candidates, seed = "graph-walk", topCandidatePool = 16) {
|
|
525508
|
+
if (candidates.length === 0)
|
|
525509
|
+
return null;
|
|
525510
|
+
const pool3 = candidates.slice(0, Math.max(1, Math.min(topCandidatePool, candidates.length)));
|
|
525511
|
+
const index = Math.min(pool3.length - 1, Math.floor(seededUnit(seed) * pool3.length));
|
|
525512
|
+
return pool3[index] ?? null;
|
|
525513
|
+
}
|
|
525514
|
+
function walkGraphFromSeed(graph, seed, options2 = {}) {
|
|
525515
|
+
const maxDepth = Math.max(0, Math.floor(options2.maxDepth ?? 2));
|
|
525516
|
+
const maxVisitedNodes = Math.max(1, Math.floor(options2.maxVisitedNodes ?? 64));
|
|
525517
|
+
const maxTraversedEdges = Math.max(1, Math.floor(options2.maxTraversedEdges ?? 160));
|
|
525518
|
+
const maxSourceEpisodes = Math.max(1, Math.floor(options2.maxSourceEpisodes ?? 80));
|
|
525519
|
+
const visited = /* @__PURE__ */ new Map();
|
|
525520
|
+
const depthByNodeId = {};
|
|
525521
|
+
const traversed = /* @__PURE__ */ new Map();
|
|
525522
|
+
const sourceEpisodeIds = [];
|
|
525523
|
+
const seenSourceEpisodes = /* @__PURE__ */ new Set();
|
|
525524
|
+
const queue = [{ node: seed.node, depth: 0 }];
|
|
525525
|
+
visited.set(seed.node.id, seed.node);
|
|
525526
|
+
depthByNodeId[seed.node.id] = 0;
|
|
525527
|
+
for (const id of seed.sourceEpisodeIds) {
|
|
525528
|
+
if (seenSourceEpisodes.size >= maxSourceEpisodes)
|
|
525529
|
+
break;
|
|
525530
|
+
seenSourceEpisodes.add(id);
|
|
525531
|
+
sourceEpisodeIds.push(id);
|
|
525532
|
+
}
|
|
525533
|
+
while (queue.length > 0) {
|
|
525534
|
+
const item = queue.shift();
|
|
525535
|
+
if (item.depth >= maxDepth)
|
|
525536
|
+
continue;
|
|
525537
|
+
const neighbors2 = graph.neighbors(item.node.id).filter(({ edge }) => relationAllowed(edge, options2)).sort((a2, b) => b.edge.confidence - a2.edge.confidence || b.node.mentionCount - a2.node.mentionCount);
|
|
525538
|
+
for (const { node, edge } of neighbors2) {
|
|
525539
|
+
if (traversed.size >= maxTraversedEdges)
|
|
525540
|
+
break;
|
|
525541
|
+
traversed.set(edgeKey(edge), edge);
|
|
525542
|
+
if (edge.sourceEpisodeId && !seenSourceEpisodes.has(edge.sourceEpisodeId) && seenSourceEpisodes.size < maxSourceEpisodes) {
|
|
525543
|
+
seenSourceEpisodes.add(edge.sourceEpisodeId);
|
|
525544
|
+
sourceEpisodeIds.push(edge.sourceEpisodeId);
|
|
525545
|
+
}
|
|
525546
|
+
if (!visited.has(node.id) && visited.size < maxVisitedNodes) {
|
|
525547
|
+
visited.set(node.id, node);
|
|
525548
|
+
depthByNodeId[node.id] = item.depth + 1;
|
|
525549
|
+
queue.push({ node, depth: item.depth + 1 });
|
|
525550
|
+
}
|
|
525551
|
+
}
|
|
525552
|
+
}
|
|
525553
|
+
return {
|
|
525554
|
+
visitedNodes: [...visited.values()],
|
|
525555
|
+
traversedEdges: [...traversed.values()],
|
|
525556
|
+
sourceEpisodeIds,
|
|
525557
|
+
depthByNodeId
|
|
525558
|
+
};
|
|
525559
|
+
}
|
|
525560
|
+
function selectAndWalkGraphCandidate(graph, candidates, options2 = {}) {
|
|
525561
|
+
const eligibleCandidates = selectInnerGraphCandidates(graph, candidates, options2);
|
|
525562
|
+
const seed = chooseInnerGraphSeed(eligibleCandidates, options2.seed, options2.topCandidatePool);
|
|
525563
|
+
if (!seed) {
|
|
525564
|
+
return {
|
|
525565
|
+
seed: null,
|
|
525566
|
+
eligibleCandidates,
|
|
525567
|
+
visitedNodes: [],
|
|
525568
|
+
traversedEdges: [],
|
|
525569
|
+
sourceEpisodeIds: [],
|
|
525570
|
+
depthByNodeId: {},
|
|
525571
|
+
fallbackReason: candidates.length === 0 ? "no episode candidates" : "no eligible inner graph nodes"
|
|
525572
|
+
};
|
|
525573
|
+
}
|
|
525574
|
+
return {
|
|
525575
|
+
seed,
|
|
525576
|
+
eligibleCandidates,
|
|
525577
|
+
...walkGraphFromSeed(graph, seed, options2)
|
|
525578
|
+
};
|
|
525579
|
+
}
|
|
525580
|
+
var init_graphWalk = __esm({
|
|
525581
|
+
"packages/memory/dist/graphWalk.js"() {
|
|
525582
|
+
"use strict";
|
|
525583
|
+
}
|
|
525584
|
+
});
|
|
525585
|
+
|
|
525383
525586
|
// packages/memory/dist/embeddings.js
|
|
525384
525587
|
async function generateEmbedding(text, config) {
|
|
525385
525588
|
const cfg = { ...DEFAULT_CONFIG5, ...config };
|
|
@@ -528615,8 +528818,8 @@ function slowWaveReplay(db, options2 = {}) {
|
|
|
528615
528818
|
try {
|
|
528616
528819
|
const referenced = db.prepare(`SELECT 1 FROM kg_edges WHERE source_episode_id = ? LIMIT 1`).get(id);
|
|
528617
528820
|
if (!referenced) {
|
|
528618
|
-
const
|
|
528619
|
-
const newNodeId = options2.graph.upsertNode({ text:
|
|
528821
|
+
const nodeText2 = `episode:${id}`;
|
|
528822
|
+
const newNodeId = options2.graph.upsertNode({ text: nodeText2, nodeType: "event" });
|
|
528620
528823
|
if (newNodeId)
|
|
528621
528824
|
integratedNodes.push(newNodeId);
|
|
528622
528825
|
}
|
|
@@ -529362,7 +529565,7 @@ var init_memoryStageContext = __esm({
|
|
|
529362
529565
|
});
|
|
529363
529566
|
|
|
529364
529567
|
// packages/memory/dist/sessionGist.js
|
|
529365
|
-
import { createHash as
|
|
529568
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
529366
529569
|
function inferDomain(input) {
|
|
529367
529570
|
const blob = [
|
|
529368
529571
|
input.goal,
|
|
@@ -529387,7 +529590,7 @@ function inferDomain(input) {
|
|
|
529387
529590
|
return ranked[0][0];
|
|
529388
529591
|
}
|
|
529389
529592
|
function computeGoalHash(goal) {
|
|
529390
|
-
return
|
|
529593
|
+
return createHash13("sha256").update(goal.trim().toLowerCase()).digest("hex").slice(0, 16);
|
|
529391
529594
|
}
|
|
529392
529595
|
function clip(text, n2) {
|
|
529393
529596
|
if (!text)
|
|
@@ -529598,12 +529801,12 @@ var init_toolOutcomes = __esm({
|
|
|
529598
529801
|
});
|
|
529599
529802
|
|
|
529600
529803
|
// packages/memory/dist/stagnationRecipes.js
|
|
529601
|
-
import { createHash as
|
|
529804
|
+
import { createHash as createHash14 } from "node:crypto";
|
|
529602
529805
|
function fingerprintSignature(fp) {
|
|
529603
529806
|
const normClusters = (fp.errorClusters ?? []).map((s2) => (s2 || "").toLowerCase().replace(/[0-9]+/g, "N").replace(/\s+/g, " ").trim()).filter(Boolean).sort();
|
|
529604
529807
|
const tool = (fp.stuckTool ?? "").toLowerCase().trim();
|
|
529605
529808
|
const blob = `tool=${tool};clusters=${normClusters.join("|")}`;
|
|
529606
|
-
return
|
|
529809
|
+
return createHash14("sha256").update(blob).digest("hex").slice(0, 16);
|
|
529607
529810
|
}
|
|
529608
529811
|
function crystallize(store2, input) {
|
|
529609
529812
|
const sig = fingerprintSignature(input.fingerprint);
|
|
@@ -529660,7 +529863,7 @@ var init_stagnationRecipes = __esm({
|
|
|
529660
529863
|
});
|
|
529661
529864
|
|
|
529662
529865
|
// packages/memory/dist/codebaseMap.js
|
|
529663
|
-
import { createHash as
|
|
529866
|
+
import { createHash as createHash15, randomUUID as randomUUID12 } from "node:crypto";
|
|
529664
529867
|
function freshNodeId() {
|
|
529665
529868
|
return randomUUID12();
|
|
529666
529869
|
}
|
|
@@ -529674,7 +529877,7 @@ var init_codebaseMap = __esm({
|
|
|
529674
529877
|
touchCount = /* @__PURE__ */ new Map();
|
|
529675
529878
|
constructor(db, repoRoot, commitSha) {
|
|
529676
529879
|
this.db = db;
|
|
529677
|
-
this.repoFp =
|
|
529880
|
+
this.repoFp = createHash15("sha256").update(`${repoRoot}::${commitSha ?? "no-commit"}`).digest("hex").slice(0, 16);
|
|
529678
529881
|
this.ensureSchema();
|
|
529679
529882
|
}
|
|
529680
529883
|
ensureSchema() {
|
|
@@ -529856,7 +530059,7 @@ var init_codebaseMap = __esm({
|
|
|
529856
530059
|
}
|
|
529857
530060
|
/** Stable composite id: `<kind>:<sha16(path)>` so insert ON CONFLICT works. */
|
|
529858
530061
|
idFor(kind, path11) {
|
|
529859
|
-
const h =
|
|
530062
|
+
const h = createHash15("sha256").update(`${this.repoFp}:${kind}:${path11}`).digest("hex").slice(0, 24);
|
|
529860
530063
|
return `${kind}-${h}`;
|
|
529861
530064
|
}
|
|
529862
530065
|
};
|
|
@@ -530020,6 +530223,7 @@ __export(dist_exports2, {
|
|
|
530020
530223
|
characteristicsForStage: () => characteristicsForStage,
|
|
530021
530224
|
checkEmbeddingAvailable: () => checkEmbeddingAvailable,
|
|
530022
530225
|
checkEmbeddingDrift: () => checkEmbeddingDrift,
|
|
530226
|
+
chooseInnerGraphSeed: () => chooseInnerGraphSeed,
|
|
530023
530227
|
closeDb: () => closeDb,
|
|
530024
530228
|
compressAndStore: () => compressAndStore,
|
|
530025
530229
|
compressToGist: () => compressToGist,
|
|
@@ -530065,6 +530269,8 @@ __export(dist_exports2, {
|
|
|
530065
530269
|
retrieveByPPR: () => retrieveByPPR,
|
|
530066
530270
|
runConsolidationCycle: () => runConsolidationCycle,
|
|
530067
530271
|
sanitizeEmotionalState: () => sanitizeEmotionalState,
|
|
530272
|
+
selectAndWalkGraphCandidate: () => selectAndWalkGraphCandidate,
|
|
530273
|
+
selectInnerGraphCandidates: () => selectInnerGraphCandidates,
|
|
530068
530274
|
selfTrustFor: () => selfTrustFor,
|
|
530069
530275
|
slowWaveReplay: () => slowWaveReplay,
|
|
530070
530276
|
splanifoldCosine: () => cosine,
|
|
@@ -530077,6 +530283,7 @@ __export(dist_exports2, {
|
|
|
530077
530283
|
suggestRegulationActions: () => suggestRegulationActions,
|
|
530078
530284
|
thresholdsForStage: () => thresholdsForStage,
|
|
530079
530285
|
tokenSimilarity: () => tokenSimilarity,
|
|
530286
|
+
walkGraphFromSeed: () => walkGraphFromSeed,
|
|
530080
530287
|
wasHesitant: () => wasHesitant
|
|
530081
530288
|
});
|
|
530082
530289
|
var init_dist7 = __esm({
|
|
@@ -530096,6 +530303,7 @@ var init_dist7 = __esm({
|
|
|
530096
530303
|
init_zettelkasten();
|
|
530097
530304
|
init_gistCompressor();
|
|
530098
530305
|
init_pprRetrieval();
|
|
530306
|
+
init_graphWalk();
|
|
530099
530307
|
init_embeddings2();
|
|
530100
530308
|
init_proceduralMemoryStore();
|
|
530101
530309
|
init_splanifold();
|
|
@@ -532316,7 +532524,7 @@ import { existsSync as existsSync72, readFileSync as readFileSync56, statSync as
|
|
|
532316
532524
|
import { execSync as execSync45 } from "node:child_process";
|
|
532317
532525
|
import { homedir as homedir23, platform as platform2, arch as arch2, totalmem as totalmem2, freemem as freemem2, hostname as hostname3 } from "node:os";
|
|
532318
532526
|
import { join as join86 } from "node:path";
|
|
532319
|
-
import { createHash as
|
|
532527
|
+
import { createHash as createHash16 } from "node:crypto";
|
|
532320
532528
|
function capturePreflightSnapshot(workingDir) {
|
|
532321
532529
|
const warnings = [];
|
|
532322
532530
|
const configFingerprints = {};
|
|
@@ -532483,7 +532691,7 @@ function expandPath(p2) {
|
|
|
532483
532691
|
return p2;
|
|
532484
532692
|
}
|
|
532485
532693
|
function sha2563(s2) {
|
|
532486
|
-
return
|
|
532694
|
+
return createHash16("sha256").update(s2).digest("hex").slice(0, 16);
|
|
532487
532695
|
}
|
|
532488
532696
|
function freeDiskBytes(path11 = "/tmp") {
|
|
532489
532697
|
try {
|
|
@@ -538505,8 +538713,8 @@ If you're stuck, try a completely different approach. Do NOT repeat what failed
|
|
|
538505
538713
|
if (process.env["OMNIUS_DISABLE_ADAPTIVE_RETRIEVAL"] !== "1") {
|
|
538506
538714
|
const goalForSig = (this._taskState.goal || "").slice(0, 200);
|
|
538507
538715
|
const recentTools = this._toolSequence.slice(-5).join("|");
|
|
538508
|
-
const { createHash:
|
|
538509
|
-
const sig =
|
|
538716
|
+
const { createHash: createHash28 } = await import("node:crypto");
|
|
538717
|
+
const sig = createHash28("sha256").update(`${goalForSig}::${recentTools}`).digest("hex").slice(0, 16);
|
|
538510
538718
|
if (this._lastPprSig === sig && this._lastPprMemoryLines.length > 0) {
|
|
538511
538719
|
compacted.push({
|
|
538512
538720
|
role: "system",
|
|
@@ -551340,10 +551548,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
551340
551548
|
wordTimestamps: false
|
|
551341
551549
|
});
|
|
551342
551550
|
if (outputDir) {
|
|
551343
|
-
const { basename:
|
|
551551
|
+
const { basename: basename30 } = await import("node:path");
|
|
551344
551552
|
const transcriptDir = join94(outputDir, ".omnius", "transcripts");
|
|
551345
551553
|
mkdirSync44(transcriptDir, { recursive: true });
|
|
551346
|
-
const outFile = join94(transcriptDir, `${
|
|
551554
|
+
const outFile = join94(transcriptDir, `${basename30(filePath)}.txt`);
|
|
551347
551555
|
writeFileSync39(outFile, result.text, "utf-8");
|
|
551348
551556
|
}
|
|
551349
551557
|
return {
|
|
@@ -551359,10 +551567,10 @@ transcribe-cli error: ${transcribeCliError}` : "";
|
|
|
551359
551567
|
const fb = await transcribeFileViaWhisper(filePath, this.config.model);
|
|
551360
551568
|
if (fb) {
|
|
551361
551569
|
if (outputDir) {
|
|
551362
|
-
const { basename:
|
|
551570
|
+
const { basename: basename30 } = await import("node:path");
|
|
551363
551571
|
const transcriptDir = join94(outputDir, ".omnius", "transcripts");
|
|
551364
551572
|
mkdirSync44(transcriptDir, { recursive: true });
|
|
551365
|
-
const outFile = join94(transcriptDir, `${
|
|
551573
|
+
const outFile = join94(transcriptDir, `${basename30(filePath)}.txt`);
|
|
551366
551574
|
writeFileSync39(outFile, fb.text, "utf-8");
|
|
551367
551575
|
}
|
|
551368
551576
|
return fb;
|
|
@@ -553610,7 +553818,7 @@ var require_websocket3 = __commonJS({
|
|
|
553610
553818
|
var http6 = __require("http");
|
|
553611
553819
|
var net5 = __require("net");
|
|
553612
553820
|
var tls2 = __require("tls");
|
|
553613
|
-
var { randomBytes: randomBytes26, createHash:
|
|
553821
|
+
var { randomBytes: randomBytes26, createHash: createHash28 } = __require("crypto");
|
|
553614
553822
|
var { Duplex: Duplex3, Readable } = __require("stream");
|
|
553615
553823
|
var { URL: URL3 } = __require("url");
|
|
553616
553824
|
var PerMessageDeflate3 = require_permessage_deflate3();
|
|
@@ -554270,7 +554478,7 @@ var require_websocket3 = __commonJS({
|
|
|
554270
554478
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
554271
554479
|
return;
|
|
554272
554480
|
}
|
|
554273
|
-
const digest3 =
|
|
554481
|
+
const digest3 = createHash28("sha1").update(key + GUID).digest("base64");
|
|
554274
554482
|
if (res.headers["sec-websocket-accept"] !== digest3) {
|
|
554275
554483
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
554276
554484
|
return;
|
|
@@ -554637,7 +554845,7 @@ var require_websocket_server2 = __commonJS({
|
|
|
554637
554845
|
var EventEmitter13 = __require("events");
|
|
554638
554846
|
var http6 = __require("http");
|
|
554639
554847
|
var { Duplex: Duplex3 } = __require("stream");
|
|
554640
|
-
var { createHash:
|
|
554848
|
+
var { createHash: createHash28 } = __require("crypto");
|
|
554641
554849
|
var extension3 = require_extension3();
|
|
554642
554850
|
var PerMessageDeflate3 = require_permessage_deflate3();
|
|
554643
554851
|
var subprotocol3 = require_subprotocol2();
|
|
@@ -554938,7 +555146,7 @@ var require_websocket_server2 = __commonJS({
|
|
|
554938
555146
|
);
|
|
554939
555147
|
}
|
|
554940
555148
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
554941
|
-
const digest3 =
|
|
555149
|
+
const digest3 = createHash28("sha1").update(key + GUID).digest("base64");
|
|
554942
555150
|
const headers = [
|
|
554943
555151
|
"HTTP/1.1 101 Switching Protocols",
|
|
554944
555152
|
"Upgrade: websocket",
|
|
@@ -555312,7 +555520,11 @@ function buildTelegramBotCommands(opts = {}) {
|
|
|
555312
555520
|
if (includeAuth) {
|
|
555313
555521
|
add2("auth", "Authenticate this Telegram user as the bot admin", "auth");
|
|
555314
555522
|
}
|
|
555523
|
+
add2("reflect", "Run scoped Telegram chat reflection", "reflect");
|
|
555524
|
+
add2("reflection", "Alias for scoped Telegram chat reflection", "reflect");
|
|
555525
|
+
add2("daydream", "Alias for scoped Telegram chat reflection", "reflect");
|
|
555315
555526
|
for (const cmd of listCommandRegistry({ includePlanned: false })) {
|
|
555527
|
+
if (cmd.name === "dream") continue;
|
|
555316
555528
|
add2(cmd.name, cmd.description || `Run /${cmd.name}`, cmd.name);
|
|
555317
555529
|
if (commands.length >= maxCommands) break;
|
|
555318
555530
|
}
|
|
@@ -558169,14 +558381,14 @@ var init_voice_session = __esm({
|
|
|
558169
558381
|
});
|
|
558170
558382
|
|
|
558171
558383
|
// packages/cli/src/tui/scoped-personality.ts
|
|
558172
|
-
import { createHash as
|
|
558384
|
+
import { createHash as createHash17 } from "node:crypto";
|
|
558173
558385
|
import { existsSync as existsSync79, mkdirSync as mkdirSync45, readFileSync as readFileSync62, writeFileSync as writeFileSync40 } from "node:fs";
|
|
558174
558386
|
import { join as join95, resolve as resolve35 } from "node:path";
|
|
558175
558387
|
function safeName(input) {
|
|
558176
558388
|
return input.replace(/[^A-Za-z0-9_.-]/g, "-").slice(0, 80) || "default";
|
|
558177
558389
|
}
|
|
558178
558390
|
function scopeHash(scope) {
|
|
558179
|
-
return
|
|
558391
|
+
return createHash17("sha1").update(`${scope.kind}:${scope.id}`).digest("hex").slice(0, 16);
|
|
558180
558392
|
}
|
|
558181
558393
|
function scopedPersonalityDir(repoRoot, kind) {
|
|
558182
558394
|
return resolve35(repoRoot, ".omnius", "scoped-personality", kind);
|
|
@@ -558214,9 +558426,9 @@ function keywords(text) {
|
|
|
558214
558426
|
return out;
|
|
558215
558427
|
}
|
|
558216
558428
|
function compactLine(text, limit = 220) {
|
|
558217
|
-
const
|
|
558218
|
-
if (
|
|
558219
|
-
return `${
|
|
558429
|
+
const compact2 = text.replace(/\s+/g, " ").trim();
|
|
558430
|
+
if (compact2.length <= limit) return compact2;
|
|
558431
|
+
return `${compact2.slice(0, Math.max(0, limit - 3)).trimEnd()}...`;
|
|
558220
558432
|
}
|
|
558221
558433
|
function newDocument(scope) {
|
|
558222
558434
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -558321,8 +558533,8 @@ function updateScopedPersonality(scope, observation) {
|
|
|
558321
558533
|
}
|
|
558322
558534
|
const relationshipHints = observation.relationshipHints ?? [];
|
|
558323
558535
|
for (const hint of relationshipHints) {
|
|
558324
|
-
const
|
|
558325
|
-
if (
|
|
558536
|
+
const clean5 = compactLine(hint, 180);
|
|
558537
|
+
if (clean5 && !doc.relationshipModel.includes(clean5)) doc.relationshipModel.push(clean5);
|
|
558326
558538
|
}
|
|
558327
558539
|
doc.relationshipModel = doc.relationshipModel.slice(-12);
|
|
558328
558540
|
if (text) {
|
|
@@ -560017,7 +560229,7 @@ var init_types = __esm({
|
|
|
560017
560229
|
});
|
|
560018
560230
|
|
|
560019
560231
|
// packages/cli/src/tui/p2p/secret-vault.ts
|
|
560020
|
-
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes19, scryptSync as scryptSync2, createHash as
|
|
560232
|
+
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes19, scryptSync as scryptSync2, createHash as createHash18 } from "node:crypto";
|
|
560021
560233
|
import { readFileSync as readFileSync64, writeFileSync as writeFileSync42, existsSync as existsSync81, mkdirSync as mkdirSync47 } from "node:fs";
|
|
560022
560234
|
import { dirname as dirname25 } from "node:path";
|
|
560023
560235
|
var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
|
|
@@ -560262,7 +560474,7 @@ var init_secret_vault = __esm({
|
|
|
560262
560474
|
/** Generate a deterministic fingerprint of vault contents (for sync verification) */
|
|
560263
560475
|
fingerprint() {
|
|
560264
560476
|
const names = Array.from(this.secrets.keys()).sort();
|
|
560265
|
-
const hash =
|
|
560477
|
+
const hash = createHash18("sha256");
|
|
560266
560478
|
for (const name10 of names) {
|
|
560267
560479
|
hash.update(name10 + ":");
|
|
560268
560480
|
hash.update(this.secrets.get(name10).value);
|
|
@@ -560277,7 +560489,7 @@ var init_secret_vault = __esm({
|
|
|
560277
560489
|
// packages/cli/src/tui/p2p/peer-mesh.ts
|
|
560278
560490
|
import { EventEmitter as EventEmitter7 } from "node:events";
|
|
560279
560491
|
import { createServer as createServer5 } from "node:http";
|
|
560280
|
-
import { randomBytes as randomBytes20, createHash as
|
|
560492
|
+
import { randomBytes as randomBytes20, createHash as createHash19, generateKeyPairSync } from "node:crypto";
|
|
560281
560493
|
var PING_INTERVAL_MS, PEER_TIMEOUT_MS, GOSSIP_INTERVAL_MS, MAX_PEERS, PeerMesh;
|
|
560282
560494
|
var init_peer_mesh = __esm({
|
|
560283
560495
|
"packages/cli/src/tui/p2p/peer-mesh.ts"() {
|
|
@@ -560294,7 +560506,7 @@ var init_peer_mesh = __esm({
|
|
|
560294
560506
|
const { publicKey: publicKey2, privateKey } = generateKeyPairSync("ed25519");
|
|
560295
560507
|
this.publicKey = publicKey2.export({ type: "spki", format: "der" });
|
|
560296
560508
|
this.privateKey = privateKey.export({ type: "pkcs8", format: "der" });
|
|
560297
|
-
this.peerId =
|
|
560509
|
+
this.peerId = createHash19("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
|
|
560298
560510
|
this.capabilities = options2.capabilities;
|
|
560299
560511
|
this.displayName = options2.displayName;
|
|
560300
560512
|
this._authKey = options2.authKey ?? randomBytes20(24).toString("base64url");
|
|
@@ -562017,7 +562229,7 @@ __export(omnius_directory_exports, {
|
|
|
562017
562229
|
import { cpSync, existsSync as existsSync83, mkdirSync as mkdirSync48, readFileSync as readFileSync66, writeFileSync as writeFileSync43, readdirSync as readdirSync26, statSync as statSync29, unlinkSync as unlinkSync14, openSync as openSync2, closeSync as closeSync2, renameSync as renameSync3 } from "node:fs";
|
|
562018
562230
|
import { join as join100, relative as relative9, basename as basename17, dirname as dirname28 } from "node:path";
|
|
562019
562231
|
import { homedir as homedir27 } from "node:os";
|
|
562020
|
-
import { createHash as
|
|
562232
|
+
import { createHash as createHash20 } from "node:crypto";
|
|
562021
562233
|
function findGitRoot(startDir) {
|
|
562022
562234
|
let dir = startDir;
|
|
562023
562235
|
const visited = /* @__PURE__ */ new Set();
|
|
@@ -562398,7 +562610,7 @@ function buildHandoffPrompt(repoRoot) {
|
|
|
562398
562610
|
return lines.join("\n");
|
|
562399
562611
|
}
|
|
562400
562612
|
function computeDedupeHash(task, savedAt) {
|
|
562401
|
-
return
|
|
562613
|
+
return createHash20("sha256").update(`${task}|${savedAt}`).digest("hex").slice(0, 16);
|
|
562402
562614
|
}
|
|
562403
562615
|
function generateSessionId() {
|
|
562404
562616
|
const timestamp = Date.now().toString(36);
|
|
@@ -562462,10 +562674,10 @@ function normalizeList(items, maxItems) {
|
|
|
562462
562674
|
const seen = /* @__PURE__ */ new Set();
|
|
562463
562675
|
const out = [];
|
|
562464
562676
|
for (const item of items) {
|
|
562465
|
-
const
|
|
562466
|
-
if (!
|
|
562467
|
-
seen.add(
|
|
562468
|
-
out.push(
|
|
562677
|
+
const clean5 = normalizeSessionText(item, 300);
|
|
562678
|
+
if (!clean5 || seen.has(clean5)) continue;
|
|
562679
|
+
seen.add(clean5);
|
|
562680
|
+
out.push(clean5);
|
|
562469
562681
|
if (out.length >= maxItems) break;
|
|
562470
562682
|
}
|
|
562471
562683
|
return out.length > 0 ? out : void 0;
|
|
@@ -562753,8 +562965,8 @@ function getLastTaskSummary(repoRoot) {
|
|
|
562753
562965
|
if (!ctx3 || ctx3.entries.length === 0) return null;
|
|
562754
562966
|
const last2 = ctx3.entries[ctx3.entries.length - 1];
|
|
562755
562967
|
const text = last2.summary || last2.task;
|
|
562756
|
-
const
|
|
562757
|
-
return
|
|
562968
|
+
const clean5 = text.replace(/^\[.*?\]\s*/, "").replace(/\s+/g, " ").trim();
|
|
562969
|
+
return clean5.length > 40 ? clean5.slice(0, 37) + "..." : clean5;
|
|
562758
562970
|
}
|
|
562759
562971
|
function saveSessionHistory(repoRoot, sessionId, contentLines, meta) {
|
|
562760
562972
|
const sessDir = join100(repoRoot, OMNIUS_DIR, SESSIONS_DIR);
|
|
@@ -562835,9 +563047,9 @@ function deleteSession(repoRoot, sessionId) {
|
|
|
562835
563047
|
}
|
|
562836
563048
|
function generateSessionName(lines) {
|
|
562837
563049
|
for (const line of lines.slice(0, 30)) {
|
|
562838
|
-
const
|
|
562839
|
-
if (
|
|
562840
|
-
const phrase =
|
|
563050
|
+
const clean5 = line.trim();
|
|
563051
|
+
if (clean5.length > 10 && !clean5.startsWith("i ") && !clean5.startsWith(" ")) {
|
|
563052
|
+
const phrase = clean5.replace(/^[>❯▹]\s*/, "").slice(0, 40);
|
|
562841
563053
|
return phrase.length > 37 ? phrase.slice(0, 37) + "..." : phrase;
|
|
562842
563054
|
}
|
|
562843
563055
|
}
|
|
@@ -565410,7 +565622,7 @@ var init_status_bar = __esm({
|
|
|
565410
565622
|
return identity3.separatorOffsets.map((offset) => chrome.contentStartCol + offset).filter((col) => col > 1 && col < termWidth);
|
|
565411
565623
|
}
|
|
565412
565624
|
if (panel.meta.kind === "system" && this._sysSeparatorOffset !== null) {
|
|
565413
|
-
const col = chrome.contentStartCol + this._sysSeparatorOffset
|
|
565625
|
+
const col = chrome.contentStartCol + this._sysSeparatorOffset;
|
|
565414
565626
|
if (col > 1 && col < termWidth) return [col];
|
|
565415
565627
|
}
|
|
565416
565628
|
return [];
|
|
@@ -567324,10 +567536,10 @@ ${CONTENT_BG_SEQ}`);
|
|
|
567324
567536
|
if (this._telegramStatus.active) {
|
|
567325
567537
|
const suffix = this._telegramStatus.activeSubAgents > 0 ? ` ${this._telegramStatus.activeSubAgents}` : "";
|
|
567326
567538
|
const label = `✈ tg${suffix}`;
|
|
567327
|
-
const
|
|
567539
|
+
const compact2 = `✈${suffix}`;
|
|
567328
567540
|
sections.push({
|
|
567329
567541
|
expanded: `\x1B[38;5;45m${label}\x1B[0m`,
|
|
567330
|
-
compact: `\x1B[38;5;45m${
|
|
567542
|
+
compact: `\x1B[38;5;45m${compact2}\x1B[0m`,
|
|
567331
567543
|
expandedW: 2 + 3 + suffix.length,
|
|
567332
567544
|
compactW: 2 + suffix.length,
|
|
567333
567545
|
empty: false
|
|
@@ -576056,17 +576268,17 @@ function toggleFocus(state) {
|
|
|
576056
576268
|
toggleFocus(state);
|
|
576057
576269
|
return;
|
|
576058
576270
|
}
|
|
576059
|
-
const
|
|
576060
|
-
if (!
|
|
576061
|
-
fn(Buffer.from(
|
|
576271
|
+
const clean5 = raw.replace(STDIN_MOUSE_FOCUS_RE, "");
|
|
576272
|
+
if (!clean5) return;
|
|
576273
|
+
fn(Buffer.from(clean5));
|
|
576062
576274
|
} else if (typeof args[0] === "string") {
|
|
576063
576275
|
if (args[0] === "") {
|
|
576064
576276
|
toggleFocus(state);
|
|
576065
576277
|
return;
|
|
576066
576278
|
}
|
|
576067
|
-
const
|
|
576068
|
-
if (!
|
|
576069
|
-
fn(
|
|
576279
|
+
const clean5 = args[0].replace(STDIN_MOUSE_FOCUS_RE, "");
|
|
576280
|
+
if (!clean5) return;
|
|
576281
|
+
fn(clean5);
|
|
576070
576282
|
} else {
|
|
576071
576283
|
fn(...args);
|
|
576072
576284
|
}
|
|
@@ -577844,8 +578056,8 @@ function normalizeAscii(ascii2, width, height) {
|
|
|
577844
578056
|
return lines.slice(0, height).map((line) => line.length > width ? line.slice(0, width) : line).join("\n").trimEnd();
|
|
577845
578057
|
}
|
|
577846
578058
|
function previewFailure(message2, width) {
|
|
577847
|
-
const
|
|
577848
|
-
const text = `[image-to-ascii preview failed: ${
|
|
578059
|
+
const clean5 = message2.replace(/\s+/g, " ").trim();
|
|
578060
|
+
const text = `[image-to-ascii preview failed: ${clean5 || "unknown error"}]`;
|
|
577849
578061
|
return text.length > width ? `${text.slice(0, Math.max(0, width - 1))}]` : text;
|
|
577850
578062
|
}
|
|
577851
578063
|
async function convertWithImageToAscii(imagePath, width, height, timeoutMs) {
|
|
@@ -580212,10 +580424,10 @@ except Exception as exc:
|
|
|
580212
580424
|
}));
|
|
580213
580425
|
}
|
|
580214
580426
|
saveSupertonicProfile(name10) {
|
|
580215
|
-
const
|
|
580216
|
-
if (!
|
|
580427
|
+
const clean5 = name10.trim().replace(/[^a-zA-Z0-9_.-]/g, "-");
|
|
580428
|
+
if (!clean5) return;
|
|
580217
580429
|
const store2 = this.loadSupertonicStore();
|
|
580218
|
-
store2.profiles[
|
|
580430
|
+
store2.profiles[clean5] = { ...store2.active };
|
|
580219
580431
|
this.saveSupertonicStore(store2);
|
|
580220
580432
|
}
|
|
580221
580433
|
loadSupertonicProfile(name10) {
|
|
@@ -589926,14 +590138,14 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
|
|
|
589926
590138
|
if (!jsonDrop.confirmed || !jsonDrop.path) {
|
|
589927
590139
|
continue;
|
|
589928
590140
|
}
|
|
589929
|
-
const { basename:
|
|
590141
|
+
const { basename: basename30, join: pathJoin } = await import("node:path");
|
|
589930
590142
|
const {
|
|
589931
590143
|
copyFileSync: copyFileSync5,
|
|
589932
590144
|
mkdirSync: mkdirSync79,
|
|
589933
590145
|
existsSync: exists2
|
|
589934
590146
|
} = await import("node:fs");
|
|
589935
590147
|
const { homedir: homedir48 } = await import("node:os");
|
|
589936
|
-
const modelName =
|
|
590148
|
+
const modelName = basename30(onnxDrop.path, ".onnx").replace(
|
|
589937
590149
|
/[^a-zA-Z0-9_-]/g,
|
|
589938
590150
|
"-"
|
|
589939
590151
|
);
|
|
@@ -590320,7 +590532,7 @@ async function handleVoiceList(ctx3, focusFilename) {
|
|
|
590320
590532
|
copyFileSync: cpf,
|
|
590321
590533
|
mkdirSync: mkd
|
|
590322
590534
|
} = __require("node:fs");
|
|
590323
|
-
const { basename:
|
|
590535
|
+
const { basename: basename30, join: pjoin } = __require("node:path");
|
|
590324
590536
|
if (!fe(src2)) {
|
|
590325
590537
|
renderError(`File not found: ${src2}`);
|
|
590326
590538
|
helpers.render();
|
|
@@ -590333,7 +590545,7 @@ async function handleVoiceList(ctx3, focusFilename) {
|
|
|
590333
590545
|
"clone-refs"
|
|
590334
590546
|
);
|
|
590335
590547
|
mkd(refsDir, { recursive: true });
|
|
590336
|
-
const destName =
|
|
590548
|
+
const destName = basename30(src2);
|
|
590337
590549
|
const dest = pjoin(refsDir, destName);
|
|
590338
590550
|
cpf(src2, dest);
|
|
590339
590551
|
renderInfo(`Imported "${destName}" → ${dest}`);
|
|
@@ -593244,9 +593456,9 @@ async function showExposeDashboard(gateway, rl, ctx3) {
|
|
|
593244
593456
|
const recentEntries = [];
|
|
593245
593457
|
for (let i2 = streamLog.length - 1; i2 >= 0 && recentEntries.length < streamAreaHeight - 1; i2--) {
|
|
593246
593458
|
const entry = streamLog[i2];
|
|
593247
|
-
const
|
|
593248
|
-
if (!
|
|
593249
|
-
const truncated =
|
|
593459
|
+
const clean5 = entry.content.replace(/\n/g, "⏎").replace(/[\x00-\x1F\x7F]/g, "");
|
|
593460
|
+
if (!clean5) continue;
|
|
593461
|
+
const truncated = clean5.length > maxContentW ? clean5.slice(0, maxContentW - 1) + "…" : clean5;
|
|
593250
593462
|
recentEntries.unshift(` \x1B[38;5;245m${truncated}\x1B[0m`);
|
|
593251
593463
|
}
|
|
593252
593464
|
while (recentEntries.length < streamAreaHeight - 1)
|
|
@@ -593978,27 +594190,468 @@ var init_project_context = __esm({
|
|
|
593978
594190
|
}
|
|
593979
594191
|
});
|
|
593980
594192
|
|
|
593981
|
-
// packages/cli/src/tui/
|
|
593982
|
-
import { mkdirSync as mkdirSync55
|
|
593983
|
-
import {
|
|
593984
|
-
function
|
|
593985
|
-
const dir = join112(repoRoot, ".omnius"
|
|
594193
|
+
// packages/cli/src/tui/memory-paths.ts
|
|
594194
|
+
import { mkdirSync as mkdirSync55 } from "node:fs";
|
|
594195
|
+
import { join as join112 } from "node:path";
|
|
594196
|
+
function omniusMemoryDbPaths(repoRoot) {
|
|
594197
|
+
const dir = join112(repoRoot, ".omnius");
|
|
593986
594198
|
mkdirSync55(dir, { recursive: true });
|
|
593987
594199
|
return {
|
|
594200
|
+
dir,
|
|
593988
594201
|
episodes: join112(dir, "episodes.db"),
|
|
593989
594202
|
knowledge: join112(dir, "knowledge.db")
|
|
593990
594203
|
};
|
|
593991
594204
|
}
|
|
594205
|
+
var init_memory_paths = __esm({
|
|
594206
|
+
"packages/cli/src/tui/memory-paths.ts"() {
|
|
594207
|
+
"use strict";
|
|
594208
|
+
}
|
|
594209
|
+
});
|
|
594210
|
+
|
|
594211
|
+
// packages/cli/src/tui/visual-identity-association.ts
|
|
594212
|
+
var visual_identity_association_exports = {};
|
|
594213
|
+
__export(visual_identity_association_exports, {
|
|
594214
|
+
associateVisualIdentityFromImage: () => associateVisualIdentityFromImage,
|
|
594215
|
+
formatVisualIdentityAssociationContext: () => formatVisualIdentityAssociationContext,
|
|
594216
|
+
stageVisualIdentityAssertion: () => stageVisualIdentityAssertion
|
|
594217
|
+
});
|
|
594218
|
+
import { basename as basename20 } from "node:path";
|
|
594219
|
+
function normalizePersonName(name10) {
|
|
594220
|
+
return name10.trim().toLowerCase().replace(/\s+/g, " ");
|
|
594221
|
+
}
|
|
593992
594222
|
function personKey(name10) {
|
|
594223
|
+
return `person:${normalizePersonName(name10)}`;
|
|
594224
|
+
}
|
|
594225
|
+
function clamp016(value2, fallback = 0) {
|
|
594226
|
+
if (typeof value2 !== "number" || !Number.isFinite(value2)) return fallback;
|
|
594227
|
+
return Math.max(0, Math.min(1, value2));
|
|
594228
|
+
}
|
|
594229
|
+
function parseStructuredIdentifyResult(result) {
|
|
594230
|
+
const raw = String(result.llmContent || result.output || "").trim();
|
|
594231
|
+
if (!raw) return { matches: [], structured: false, raw };
|
|
594232
|
+
let parsed = null;
|
|
594233
|
+
try {
|
|
594234
|
+
parsed = JSON.parse(raw);
|
|
594235
|
+
} catch {
|
|
594236
|
+
return { matches: [], structured: false, raw };
|
|
594237
|
+
}
|
|
594238
|
+
const faces = Array.isArray(parsed.faces) ? parsed.faces : [];
|
|
594239
|
+
const matches = faces.filter((face) => face["identified"] === true && typeof face["name"] === "string" && String(face["name"]).trim()).map((face) => ({
|
|
594240
|
+
name: String(face["name"]).trim(),
|
|
594241
|
+
personId: typeof face["person_id"] === "string" ? face["person_id"] : void 0,
|
|
594242
|
+
confidence: clamp016(face["confidence"], 0),
|
|
594243
|
+
margin: typeof face["margin"] === "number" ? face["margin"] : void 0,
|
|
594244
|
+
bbox: Array.isArray(face["bbox"]) ? face["bbox"].map((n2) => Number(n2)).filter(Number.isFinite) : void 0
|
|
594245
|
+
}));
|
|
594246
|
+
return { matches, structured: true, raw };
|
|
594247
|
+
}
|
|
594248
|
+
function parseDetectedFaceCount(result) {
|
|
594249
|
+
const raw = String(result.llmContent || result.output || "").trim();
|
|
594250
|
+
if (!raw) return 0;
|
|
594251
|
+
try {
|
|
594252
|
+
const parsed = JSON.parse(raw);
|
|
594253
|
+
if (Array.isArray(parsed.faces)) return parsed.faces.length;
|
|
594254
|
+
if (typeof parsed.total === "number" && Number.isFinite(parsed.total)) return Math.max(0, Math.floor(parsed.total));
|
|
594255
|
+
} catch {
|
|
594256
|
+
}
|
|
594257
|
+
return 0;
|
|
594258
|
+
}
|
|
594259
|
+
function readMetadataObject(value2) {
|
|
594260
|
+
return value2 && typeof value2 === "object" ? value2 : {};
|
|
594261
|
+
}
|
|
594262
|
+
function sameScope(a2, b) {
|
|
594263
|
+
if (!b || !a2 || typeof a2 !== "object") return false;
|
|
594264
|
+
const raw = a2;
|
|
594265
|
+
return String(raw["kind"] ?? "") === String(b.kind) && String(raw["id"] ?? "") === String(b.id);
|
|
594266
|
+
}
|
|
594267
|
+
function episodeMatchesScope(ep, scope, sessionId) {
|
|
594268
|
+
if (!scope) return true;
|
|
594269
|
+
const metadata = readMetadataObject(ep.metadata);
|
|
594270
|
+
if (sameScope(metadata["scope"], scope)) return true;
|
|
594271
|
+
if (sessionId && ep.sessionId === sessionId) return true;
|
|
594272
|
+
const chatId = metadata["chat_id"] ?? metadata["chatId"];
|
|
594273
|
+
if ((scope.kind === "group" || scope.kind === "private") && chatId != null && String(chatId) === String(scope.id)) return true;
|
|
594274
|
+
const telegram = readMetadataObject(metadata["telegram"]);
|
|
594275
|
+
if ((scope.kind === "group" || scope.kind === "private") && telegram["chatId"] != null && String(telegram["chatId"]) === String(scope.id)) return true;
|
|
594276
|
+
return false;
|
|
594277
|
+
}
|
|
594278
|
+
function episodeSenderDisplay(ep) {
|
|
594279
|
+
const metadata = readMetadataObject(ep.metadata);
|
|
594280
|
+
const sender = readMetadataObject(metadata["sender"]);
|
|
594281
|
+
return String(sender["displayName"] || sender["username"] || sender["id"] || "").trim() || void 0;
|
|
594282
|
+
}
|
|
594283
|
+
function episodeMessageId(ep) {
|
|
594284
|
+
const metadata = readMetadataObject(ep.metadata);
|
|
594285
|
+
const message2 = readMetadataObject(metadata["message"]);
|
|
594286
|
+
return message2["id"];
|
|
594287
|
+
}
|
|
594288
|
+
function episodeSurface(ep) {
|
|
594289
|
+
const metadata = readMetadataObject(ep.metadata);
|
|
594290
|
+
return typeof metadata["sourceSurface"] === "string" ? metadata["sourceSurface"] : void 0;
|
|
594291
|
+
}
|
|
594292
|
+
function compactContent(value2, max = 220) {
|
|
594293
|
+
const clean5 = value2.replace(/\s+/g, " ").trim();
|
|
594294
|
+
return clean5.length > max ? `${clean5.slice(0, max - 1)}...` : clean5;
|
|
594295
|
+
}
|
|
594296
|
+
function pendingConsumedIds(store2, scope, sessionId) {
|
|
594297
|
+
const consumed = /* @__PURE__ */ new Set();
|
|
594298
|
+
for (const ep of store2.recent(250)) {
|
|
594299
|
+
if (!episodeMatchesScope(ep, scope, sessionId)) continue;
|
|
594300
|
+
const metadata = readMetadataObject(ep.metadata);
|
|
594301
|
+
const consumedMeta = readMetadataObject(metadata["identityPendingConsumed"]);
|
|
594302
|
+
const pendingId = String(consumedMeta["pendingId"] || "").trim();
|
|
594303
|
+
if (pendingId) consumed.add(pendingId);
|
|
594304
|
+
}
|
|
594305
|
+
return consumed;
|
|
594306
|
+
}
|
|
594307
|
+
function activePendingVisualIdentities(store2, scope, sessionId, limit = 3) {
|
|
594308
|
+
const now = Date.now();
|
|
594309
|
+
const consumed = pendingConsumedIds(store2, scope, sessionId);
|
|
594310
|
+
const pending = [];
|
|
594311
|
+
for (const ep of store2.recent(250)) {
|
|
594312
|
+
if (!episodeMatchesScope(ep, scope, sessionId)) continue;
|
|
594313
|
+
const metadata = readMetadataObject(ep.metadata);
|
|
594314
|
+
const meta = readMetadataObject(metadata["identityPending"]);
|
|
594315
|
+
if (String(meta["kind"] || "") !== "visual_identity") continue;
|
|
594316
|
+
const pendingId = String(meta["pendingId"] || "").trim();
|
|
594317
|
+
const name10 = String(meta["name"] || "").trim();
|
|
594318
|
+
if (!pendingId || !name10 || consumed.has(pendingId)) continue;
|
|
594319
|
+
const expiresAt = typeof meta["expiresAt"] === "number" ? meta["expiresAt"] : 0;
|
|
594320
|
+
if (expiresAt > 0 && expiresAt < now) continue;
|
|
594321
|
+
pending.push({
|
|
594322
|
+
pendingId,
|
|
594323
|
+
name: name10,
|
|
594324
|
+
relation: String(meta["relation"] || "depicts"),
|
|
594325
|
+
confidence: clamp016(meta["confidence"], 0.92),
|
|
594326
|
+
note: typeof meta["note"] === "string" ? meta["note"] : void 0,
|
|
594327
|
+
episodeId: ep.id,
|
|
594328
|
+
createdAt: ep.timestamp,
|
|
594329
|
+
expiresAt,
|
|
594330
|
+
sender: readMetadataObject(metadata["sender"]),
|
|
594331
|
+
message: readMetadataObject(metadata["message"])
|
|
594332
|
+
});
|
|
594333
|
+
if (pending.length >= limit) break;
|
|
594334
|
+
}
|
|
594335
|
+
return pending;
|
|
594336
|
+
}
|
|
594337
|
+
function recallPersonEpisodes(store2, graph, name10, scope, sessionId, excludedEpisodeIds, limit) {
|
|
594338
|
+
const person = graph.findNode(personKey(name10), "person");
|
|
594339
|
+
if (!person) return [];
|
|
594340
|
+
const edges = graph.currentEdges(person.id);
|
|
594341
|
+
const ids = /* @__PURE__ */ new Set();
|
|
594342
|
+
for (const edge of edges) {
|
|
594343
|
+
if (edge.sourceEpisodeId && !excludedEpisodeIds.has(edge.sourceEpisodeId)) ids.add(edge.sourceEpisodeId);
|
|
594344
|
+
}
|
|
594345
|
+
const episodes = [...ids].map((id) => store2.get(id)).filter((ep) => Boolean(ep)).filter((ep) => episodeMatchesScope(ep, scope, sessionId)).sort((a2, b) => b.timestamp - a2.timestamp).slice(0, limit);
|
|
594346
|
+
return episodes.map((ep) => ({
|
|
594347
|
+
id: ep.id,
|
|
594348
|
+
timestamp: ep.timestamp,
|
|
594349
|
+
modality: ep.modality,
|
|
594350
|
+
content: compactContent(ep.gist || ep.content),
|
|
594351
|
+
sourceSurface: episodeSurface(ep),
|
|
594352
|
+
messageId: episodeMessageId(ep),
|
|
594353
|
+
senderDisplay: episodeSenderDisplay(ep)
|
|
594354
|
+
}));
|
|
594355
|
+
}
|
|
594356
|
+
function formatTimestamp2(ms) {
|
|
594357
|
+
try {
|
|
594358
|
+
return new Date(ms).toISOString();
|
|
594359
|
+
} catch {
|
|
594360
|
+
return String(ms);
|
|
594361
|
+
}
|
|
594362
|
+
}
|
|
594363
|
+
function formatVisualIdentityAssociationContext(result) {
|
|
594364
|
+
if (result.matches.length === 0 && result.pendingApplied.length === 0 && result.pendingSkipped.length === 0 && result.unknownFaceCount === 0) {
|
|
594365
|
+
return "";
|
|
594366
|
+
}
|
|
594367
|
+
const lines = [];
|
|
594368
|
+
if (result.pendingApplied.length > 0) {
|
|
594369
|
+
lines.push("## Pending Visual Identity Applied");
|
|
594370
|
+
lines.push("A prior explicit user identity assertion was waiting for the next image in this same scope. It has now been linked to this image.");
|
|
594371
|
+
for (const pending of result.pendingApplied) {
|
|
594372
|
+
lines.push(`- ${pending.name} confidence=${pending.confidence.toFixed(2)} pending_id=${pending.pendingId}`);
|
|
594373
|
+
}
|
|
594374
|
+
}
|
|
594375
|
+
if (result.matches.length > 0) {
|
|
594376
|
+
lines.push("## Scoped Visual Identity Recall");
|
|
594377
|
+
lines.push("Prior enrolled visual-memory face match found for the current image. This is not a new identity assertion from the caption or prompt.");
|
|
594378
|
+
for (const match of result.matches) {
|
|
594379
|
+
const confidence2 = Number.isFinite(match.confidence) ? ` confidence=${match.confidence.toFixed(2)}` : "";
|
|
594380
|
+
const margin = typeof match.margin === "number" ? ` margin=${match.margin.toFixed(2)}` : "";
|
|
594381
|
+
lines.push(`- ${match.name}${confidence2}${margin}`);
|
|
594382
|
+
}
|
|
594383
|
+
if (result.recalledEpisodes.length) {
|
|
594384
|
+
lines.push("Scoped related memory:");
|
|
594385
|
+
for (const ep of result.recalledEpisodes) {
|
|
594386
|
+
const sender = ep.senderDisplay ? ` ${ep.senderDisplay}:` : "";
|
|
594387
|
+
const msg = ep.messageId != null ? ` message=${ep.messageId}` : "";
|
|
594388
|
+
lines.push(`- ${formatTimestamp2(ep.timestamp)}${msg}${sender} ${ep.content}`);
|
|
594389
|
+
}
|
|
594390
|
+
} else {
|
|
594391
|
+
lines.push("Scoped related memory: no prior same-scope episode found beyond the enrolled visual identity.");
|
|
594392
|
+
}
|
|
594393
|
+
}
|
|
594394
|
+
if (result.pendingSkipped.length > 0) {
|
|
594395
|
+
lines.push("## Pending Visual Identity Not Applied");
|
|
594396
|
+
for (const skipped of result.pendingSkipped) {
|
|
594397
|
+
lines.push(`- ${skipped.name}: ${skipped.reason}`);
|
|
594398
|
+
}
|
|
594399
|
+
}
|
|
594400
|
+
if (result.matches.length === 0 && result.pendingApplied.length === 0 && result.unknownFaceCount > 0) {
|
|
594401
|
+
lines.push("## Unknown Visual Identity Candidate");
|
|
594402
|
+
lines.push(`${result.unknownFaceCount} face(s) detected, but no prior enrolled identity matched in this scope.`);
|
|
594403
|
+
lines.push("If the user's task depends on who this is, ask who the person is and offer to remember them. Do not guess a real identity.");
|
|
594404
|
+
}
|
|
594405
|
+
lines.push("Use identity_memory only when the user explicitly names, stages, enrolls, asks to identify, or asks to recall identity evidence.");
|
|
594406
|
+
return lines.join("\n");
|
|
594407
|
+
}
|
|
594408
|
+
function stageVisualIdentityAssertion(options2) {
|
|
594409
|
+
const name10 = options2.name.trim();
|
|
594410
|
+
if (!name10) throw new Error("Name is required to stage a visual identity assertion.");
|
|
594411
|
+
const pendingId = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
594412
|
+
const expiresAt = Date.now() + (typeof options2.expiresInMs === "number" && Number.isFinite(options2.expiresInMs) ? Math.max(6e4, Math.min(864e5, options2.expiresInMs)) : 72e5);
|
|
594413
|
+
const dbPaths = omniusMemoryDbPaths(options2.repoRoot);
|
|
594414
|
+
const graph = new TemporalGraph(dbPaths.knowledge);
|
|
594415
|
+
const store2 = new EpisodeStore(dbPaths.episodes, graph);
|
|
594416
|
+
try {
|
|
594417
|
+
const service = new MultimodalIdentityService({ episodeStore: store2, graph });
|
|
594418
|
+
const result = service.ingest({
|
|
594419
|
+
sourceSurface: options2.sourceSurface,
|
|
594420
|
+
sessionId: options2.sessionId,
|
|
594421
|
+
scope: options2.scope,
|
|
594422
|
+
sender: options2.sender,
|
|
594423
|
+
message: options2.message,
|
|
594424
|
+
replyTo: options2.replyTo,
|
|
594425
|
+
modality: "social",
|
|
594426
|
+
content: options2.note || `Pending visual identity assertion for next image: ${name10}`,
|
|
594427
|
+
labels: ["pending_visual_identity", name10],
|
|
594428
|
+
metadata: {
|
|
594429
|
+
identityPending: {
|
|
594430
|
+
kind: "visual_identity",
|
|
594431
|
+
pendingId,
|
|
594432
|
+
target: "next_visual_media",
|
|
594433
|
+
name: name10,
|
|
594434
|
+
relation: options2.relation || "depicts",
|
|
594435
|
+
confidence: clamp016(options2.confidence, 0.92),
|
|
594436
|
+
note: options2.note,
|
|
594437
|
+
createdAt: Date.now(),
|
|
594438
|
+
expiresAt
|
|
594439
|
+
}
|
|
594440
|
+
},
|
|
594441
|
+
identityAssertions: [{
|
|
594442
|
+
name: name10,
|
|
594443
|
+
relation: options2.relation || "named_as",
|
|
594444
|
+
confidence: clamp016(options2.confidence, 0.92),
|
|
594445
|
+
assertedBy: options2.sender,
|
|
594446
|
+
note: options2.note || "Explicit user-provided identity staged for the next visual media."
|
|
594447
|
+
}]
|
|
594448
|
+
});
|
|
594449
|
+
return { pendingId, episodeId: result.episodeId, name: name10, expiresAt };
|
|
594450
|
+
} finally {
|
|
594451
|
+
store2.close();
|
|
594452
|
+
graph.close();
|
|
594453
|
+
}
|
|
594454
|
+
}
|
|
594455
|
+
async function associateVisualIdentityFromImage(options2) {
|
|
594456
|
+
const startedAt2 = Date.now();
|
|
594457
|
+
const visual = options2.visualMemoryTool ?? new VisualMemoryTool();
|
|
594458
|
+
const identify2 = await visual.execute({
|
|
594459
|
+
action: "identify",
|
|
594460
|
+
image: options2.imagePath,
|
|
594461
|
+
threshold: typeof options2.threshold === "number" ? options2.threshold : 0.5,
|
|
594462
|
+
format: "json"
|
|
594463
|
+
});
|
|
594464
|
+
const parsed = parseStructuredIdentifyResult(identify2);
|
|
594465
|
+
if (!identify2.success) {
|
|
594466
|
+
return {
|
|
594467
|
+
matches: [],
|
|
594468
|
+
unknownFaceCount: 0,
|
|
594469
|
+
pendingApplied: [],
|
|
594470
|
+
pendingSkipped: [],
|
|
594471
|
+
recalledEpisodes: [],
|
|
594472
|
+
committedEpisodeIds: [],
|
|
594473
|
+
structured: parsed.structured,
|
|
594474
|
+
contextBlock: "",
|
|
594475
|
+
degradedReason: identify2.error || "visual_memory identify failed",
|
|
594476
|
+
rawIdentifyOutput: parsed.raw
|
|
594477
|
+
};
|
|
594478
|
+
}
|
|
594479
|
+
if (!parsed.structured) {
|
|
594480
|
+
return {
|
|
594481
|
+
matches: [],
|
|
594482
|
+
unknownFaceCount: 0,
|
|
594483
|
+
pendingApplied: [],
|
|
594484
|
+
pendingSkipped: [],
|
|
594485
|
+
recalledEpisodes: [],
|
|
594486
|
+
committedEpisodeIds: [],
|
|
594487
|
+
structured: false,
|
|
594488
|
+
contextBlock: "",
|
|
594489
|
+
degradedReason: "visual_memory identify did not return structured JSON",
|
|
594490
|
+
rawIdentifyOutput: parsed.raw
|
|
594491
|
+
};
|
|
594492
|
+
}
|
|
594493
|
+
const dbPaths = omniusMemoryDbPaths(options2.repoRoot);
|
|
594494
|
+
const graph = new TemporalGraph(dbPaths.knowledge);
|
|
594495
|
+
const store2 = new EpisodeStore(dbPaths.episodes, graph);
|
|
594496
|
+
const committedEpisodeIds = [];
|
|
594497
|
+
const pendingApplied = [];
|
|
594498
|
+
const pendingSkipped = [];
|
|
594499
|
+
let unknownFaceCount = 0;
|
|
594500
|
+
try {
|
|
594501
|
+
const shouldCommit = options2.commitMatches !== false;
|
|
594502
|
+
const service = new MultimodalIdentityService({ episodeStore: store2, graph });
|
|
594503
|
+
if (parsed.matches.length === 0) {
|
|
594504
|
+
try {
|
|
594505
|
+
const detect2 = await visual.execute({ action: "detect", image: options2.imagePath, format: "json" });
|
|
594506
|
+
if (detect2.success) unknownFaceCount = parseDetectedFaceCount(detect2);
|
|
594507
|
+
} catch {
|
|
594508
|
+
}
|
|
594509
|
+
}
|
|
594510
|
+
if (shouldCommit && parsed.matches.length > 0) {
|
|
594511
|
+
for (const match of parsed.matches) {
|
|
594512
|
+
const result2 = service.ingest({
|
|
594513
|
+
sourceSurface: options2.sourceSurface,
|
|
594514
|
+
sessionId: options2.sessionId,
|
|
594515
|
+
scope: options2.scope,
|
|
594516
|
+
sender: options2.sender,
|
|
594517
|
+
message: options2.message,
|
|
594518
|
+
replyTo: options2.replyTo,
|
|
594519
|
+
modality: "visual",
|
|
594520
|
+
content: `Prior enrolled visual identity match: ${match.name}`,
|
|
594521
|
+
extractedContent: options2.extractedContent,
|
|
594522
|
+
media: options2.media ?? { path: options2.imagePath, mediaType: "photo" },
|
|
594523
|
+
labels: ["visual_identity_match", match.name],
|
|
594524
|
+
metadata: {
|
|
594525
|
+
visualIdentityAssociation: {
|
|
594526
|
+
version: 1,
|
|
594527
|
+
imagePath: options2.imagePath,
|
|
594528
|
+
name: match.name,
|
|
594529
|
+
personId: match.personId,
|
|
594530
|
+
confidence: match.confidence,
|
|
594531
|
+
margin: match.margin,
|
|
594532
|
+
elapsedMs: Date.now() - startedAt2
|
|
594533
|
+
}
|
|
594534
|
+
},
|
|
594535
|
+
identityAssertions: [{
|
|
594536
|
+
name: match.name,
|
|
594537
|
+
relation: "same_person_candidate",
|
|
594538
|
+
confidence: match.confidence,
|
|
594539
|
+
assertedBy: { id: "visual_memory", displayName: "visual_memory", isBot: true },
|
|
594540
|
+
note: `Prior enrolled visual-memory face match for ${basename20(options2.imagePath)}`
|
|
594541
|
+
}]
|
|
594542
|
+
});
|
|
594543
|
+
if (result2.episodeId) committedEpisodeIds.push(result2.episodeId);
|
|
594544
|
+
}
|
|
594545
|
+
}
|
|
594546
|
+
if (shouldCommit && parsed.matches.length === 0) {
|
|
594547
|
+
const pending = activePendingVisualIdentities(store2, options2.scope, options2.sessionId);
|
|
594548
|
+
for (const item of pending) {
|
|
594549
|
+
const enrollment = await visual.execute({ action: "enroll", image: options2.imagePath, name: item.name });
|
|
594550
|
+
if (!enrollment.success) {
|
|
594551
|
+
pendingSkipped.push({
|
|
594552
|
+
pendingId: item.pendingId,
|
|
594553
|
+
name: item.name,
|
|
594554
|
+
reason: enrollment.error || enrollment.output || "face enrollment failed"
|
|
594555
|
+
});
|
|
594556
|
+
continue;
|
|
594557
|
+
}
|
|
594558
|
+
const result2 = service.ingest({
|
|
594559
|
+
sourceSurface: options2.sourceSurface,
|
|
594560
|
+
sessionId: options2.sessionId,
|
|
594561
|
+
scope: options2.scope,
|
|
594562
|
+
sender: options2.sender,
|
|
594563
|
+
message: options2.message,
|
|
594564
|
+
replyTo: options2.replyTo,
|
|
594565
|
+
modality: "visual",
|
|
594566
|
+
content: `Applied pending visual identity assertion: ${item.name}`,
|
|
594567
|
+
extractedContent: options2.extractedContent,
|
|
594568
|
+
media: options2.media ?? { path: options2.imagePath, mediaType: "photo" },
|
|
594569
|
+
labels: ["pending_visual_identity_applied", item.name],
|
|
594570
|
+
metadata: {
|
|
594571
|
+
identityPendingConsumed: {
|
|
594572
|
+
pendingId: item.pendingId,
|
|
594573
|
+
sourceEpisodeId: item.episodeId,
|
|
594574
|
+
name: item.name,
|
|
594575
|
+
imagePath: options2.imagePath,
|
|
594576
|
+
consumedAt: Date.now(),
|
|
594577
|
+
enrollmentOutput: enrollment.output
|
|
594578
|
+
}
|
|
594579
|
+
},
|
|
594580
|
+
identityAssertions: [{
|
|
594581
|
+
name: item.name,
|
|
594582
|
+
relation: "depicts",
|
|
594583
|
+
confidence: item.confidence,
|
|
594584
|
+
assertedBy: item.sender || options2.sender,
|
|
594585
|
+
note: item.note || `Applied explicit pending identity assertion to ${basename20(options2.imagePath)}`
|
|
594586
|
+
}]
|
|
594587
|
+
});
|
|
594588
|
+
if (result2.episodeId) committedEpisodeIds.push(result2.episodeId);
|
|
594589
|
+
pendingApplied.push({
|
|
594590
|
+
pendingId: item.pendingId,
|
|
594591
|
+
name: item.name,
|
|
594592
|
+
confidence: item.confidence,
|
|
594593
|
+
sourceEpisodeId: item.episodeId,
|
|
594594
|
+
committedEpisodeId: result2.episodeId,
|
|
594595
|
+
enrollmentOutput: enrollment.output
|
|
594596
|
+
});
|
|
594597
|
+
}
|
|
594598
|
+
}
|
|
594599
|
+
const excluded = new Set(committedEpisodeIds);
|
|
594600
|
+
const limit = typeof options2.limit === "number" && Number.isFinite(options2.limit) ? Math.max(1, Math.min(12, Math.floor(options2.limit))) : 5;
|
|
594601
|
+
const recalledEpisodes = [];
|
|
594602
|
+
const seen = /* @__PURE__ */ new Set();
|
|
594603
|
+
const namesForRecall = [
|
|
594604
|
+
...parsed.matches.map((match) => match.name),
|
|
594605
|
+
...pendingApplied.map((pending) => pending.name)
|
|
594606
|
+
];
|
|
594607
|
+
for (const name10 of namesForRecall) {
|
|
594608
|
+
for (const ep of recallPersonEpisodes(store2, graph, name10, options2.scope, options2.sessionId, excluded, limit)) {
|
|
594609
|
+
if (seen.has(ep.id)) continue;
|
|
594610
|
+
seen.add(ep.id);
|
|
594611
|
+
recalledEpisodes.push(ep);
|
|
594612
|
+
}
|
|
594613
|
+
}
|
|
594614
|
+
const result = {
|
|
594615
|
+
matches: parsed.matches,
|
|
594616
|
+
unknownFaceCount,
|
|
594617
|
+
pendingApplied,
|
|
594618
|
+
pendingSkipped,
|
|
594619
|
+
recalledEpisodes: recalledEpisodes.slice(0, limit),
|
|
594620
|
+
committedEpisodeIds,
|
|
594621
|
+
structured: true,
|
|
594622
|
+
contextBlock: "",
|
|
594623
|
+
rawIdentifyOutput: parsed.raw
|
|
594624
|
+
};
|
|
594625
|
+
result.contextBlock = formatVisualIdentityAssociationContext(result);
|
|
594626
|
+
return result;
|
|
594627
|
+
} finally {
|
|
594628
|
+
store2.close();
|
|
594629
|
+
graph.close();
|
|
594630
|
+
}
|
|
594631
|
+
}
|
|
594632
|
+
var init_visual_identity_association = __esm({
|
|
594633
|
+
"packages/cli/src/tui/visual-identity-association.ts"() {
|
|
594634
|
+
"use strict";
|
|
594635
|
+
init_dist7();
|
|
594636
|
+
init_dist5();
|
|
594637
|
+
init_memory_paths();
|
|
594638
|
+
}
|
|
594639
|
+
});
|
|
594640
|
+
|
|
594641
|
+
// packages/cli/src/tui/identity-memory-tool.ts
|
|
594642
|
+
import { existsSync as existsSync98 } from "node:fs";
|
|
594643
|
+
import { basename as basename21, extname as extname14, resolve as resolve39 } from "node:path";
|
|
594644
|
+
function personKey2(name10) {
|
|
593993
594645
|
return `person:${name10.trim().toLowerCase().replace(/\s+/g, " ")}`;
|
|
593994
594646
|
}
|
|
593995
594647
|
function coerceAction(value2) {
|
|
593996
594648
|
const raw = String(value2 || "recall").trim().toLowerCase();
|
|
593997
594649
|
if (raw === "assert" || raw === "remember" || raw === "name") return "assert_identity";
|
|
594650
|
+
if (raw === "stage" || raw === "pending" || raw === "next" || raw === "expect") return "stage_identity";
|
|
593998
594651
|
if (raw === "enroll" || raw === "enrol" || raw === "face") return "enroll_face";
|
|
593999
594652
|
if (raw === "who" || raw === "recognize" || raw === "recognise") return "identify";
|
|
594000
594653
|
if (raw === "list") return "inspect";
|
|
594001
|
-
if (raw === "assert_identity" || raw === "enroll_face" || raw === "identify" || raw === "recall" || raw === "inspect") {
|
|
594654
|
+
if (raw === "assert_identity" || raw === "stage_identity" || raw === "enroll_face" || raw === "identify" || raw === "recall" || raw === "inspect") {
|
|
594002
594655
|
return raw;
|
|
594003
594656
|
}
|
|
594004
594657
|
return "recall";
|
|
@@ -594056,7 +594709,7 @@ async function resolveMediaFromArgs(args, opts) {
|
|
|
594056
594709
|
path: path11,
|
|
594057
594710
|
media,
|
|
594058
594711
|
modality: inferModality(media),
|
|
594059
|
-
label:
|
|
594712
|
+
label: basename21(path11)
|
|
594060
594713
|
};
|
|
594061
594714
|
}
|
|
594062
594715
|
function edgeDirection(edge, nodeId, otherText) {
|
|
@@ -594067,7 +594720,10 @@ function formatIdentityMemoryContext(surface) {
|
|
|
594067
594720
|
return [
|
|
594068
594721
|
"Identity memory contract:",
|
|
594069
594722
|
"- Use identity_memory when a user explicitly asks you to remember, name, enroll, identify, or recall a person/voice/object identity from scoped media.",
|
|
594070
|
-
"- Do not infer a real person's identity from an image on your own. Store identity only from an explicit user assertion or from a prior enrolled match.",
|
|
594723
|
+
"- Do not infer a real person's identity from an image on your own. Store identity only from an explicit user assertion or from a structured prior enrolled visual-memory match.",
|
|
594724
|
+
"- Image ingress may include a Scoped Visual Identity Recall block. Treat it as prior enrolled evidence scoped to the current chat/session, not as a new caption-derived assertion.",
|
|
594725
|
+
"- If the user gives a name before the image arrives, or says the next image/media will be someone, call identity_memory with action='stage_identity', name='<explicit name>'. The next same-scope image can then link and enroll that face.",
|
|
594726
|
+
"- If image ingress includes Unknown Visual Identity Candidate, ask who the person is only when identity matters to the user's task; if they provide a name, call identity_memory.",
|
|
594071
594727
|
"- For Telegram replies, use media='reply' when the user is naming or asking about the replied-to media; use media='latest' for the latest media in the same chat.",
|
|
594072
594728
|
"- For visual identity assertions such as 'this is Amy', call identity_memory with action='assert_identity', name='Amy', relation='depicts'. The tool stores graph evidence and attempts face enrollment.",
|
|
594073
594729
|
"- For 'who is this?' on an image, call identity_memory with action='identify'.",
|
|
@@ -594080,6 +594736,8 @@ var init_identity_memory_tool = __esm({
|
|
|
594080
594736
|
"use strict";
|
|
594081
594737
|
init_dist7();
|
|
594082
594738
|
init_dist5();
|
|
594739
|
+
init_memory_paths();
|
|
594740
|
+
init_visual_identity_association();
|
|
594083
594741
|
IdentityMemoryTool = class {
|
|
594084
594742
|
constructor(repoRoot, opts = {}) {
|
|
594085
594743
|
this.repoRoot = repoRoot;
|
|
@@ -594088,14 +594746,14 @@ var init_identity_memory_tool = __esm({
|
|
|
594088
594746
|
repoRoot;
|
|
594089
594747
|
opts;
|
|
594090
594748
|
name = "identity_memory";
|
|
594091
|
-
description = "Scoped multimodal identity memory. Agentically records explicit identity assertions, enrolls visual face evidence, identifies enrolled faces, and recalls stored person evidence without regex shortcuts.";
|
|
594749
|
+
description = "Scoped multimodal identity memory. Agentically records explicit identity assertions, stages next-media identity assertions, enrolls visual face evidence, identifies enrolled faces, and recalls stored person evidence without regex shortcuts.";
|
|
594092
594750
|
parameters = {
|
|
594093
594751
|
type: "object",
|
|
594094
594752
|
properties: {
|
|
594095
594753
|
action: {
|
|
594096
594754
|
type: "string",
|
|
594097
|
-
enum: ["assert_identity", "enroll_face", "identify", "recall", "inspect"],
|
|
594098
|
-
description: "assert_identity/enroll_face store explicit
|
|
594755
|
+
enum: ["assert_identity", "stage_identity", "enroll_face", "identify", "recall", "inspect"],
|
|
594756
|
+
description: "assert_identity/enroll_face store explicit current-media evidence; stage_identity stores an explicit name for the next visual media in this scope; identify recognizes current media; recall/inspect read stored identity evidence."
|
|
594099
594757
|
},
|
|
594100
594758
|
name: {
|
|
594101
594759
|
type: "string",
|
|
@@ -594133,6 +594791,10 @@ var init_identity_memory_tool = __esm({
|
|
|
594133
594791
|
limit: {
|
|
594134
594792
|
type: "number",
|
|
594135
594793
|
description: "Recall/inspect result limit. Default 12."
|
|
594794
|
+
},
|
|
594795
|
+
expires_in_minutes: {
|
|
594796
|
+
type: "number",
|
|
594797
|
+
description: "For stage_identity, how long the pending next-image assertion remains active. Default 120 minutes."
|
|
594136
594798
|
}
|
|
594137
594799
|
},
|
|
594138
594800
|
required: ["action"]
|
|
@@ -594140,7 +594802,7 @@ var init_identity_memory_tool = __esm({
|
|
|
594140
594802
|
async execute(args) {
|
|
594141
594803
|
const startedAt2 = Date.now();
|
|
594142
594804
|
const action = coerceAction(args["action"]);
|
|
594143
|
-
const dbPaths =
|
|
594805
|
+
const dbPaths = omniusMemoryDbPaths(this.repoRoot);
|
|
594144
594806
|
const store2 = new EpisodeStore(dbPaths.episodes);
|
|
594145
594807
|
const graph = new TemporalGraph(dbPaths.knowledge);
|
|
594146
594808
|
try {
|
|
@@ -594150,6 +594812,9 @@ var init_identity_memory_tool = __esm({
|
|
|
594150
594812
|
if (action === "recall" || action === "inspect") {
|
|
594151
594813
|
return this.recall(args, startedAt2, graph);
|
|
594152
594814
|
}
|
|
594815
|
+
if (action === "stage_identity") {
|
|
594816
|
+
return this.stageIdentity(args, startedAt2);
|
|
594817
|
+
}
|
|
594153
594818
|
return await this.assertIdentity(action, args, startedAt2, store2, graph);
|
|
594154
594819
|
} finally {
|
|
594155
594820
|
store2.close();
|
|
@@ -594176,6 +594841,7 @@ var init_identity_memory_tool = __esm({
|
|
|
594176
594841
|
const content = evidenceNote || this.opts.message?.text || (media?.caption ? `Identity assertion for ${name10}: ${media.caption}` : `Identity assertion for ${name10}`);
|
|
594177
594842
|
const result = service.ingest({
|
|
594178
594843
|
sourceSurface: this.opts.sourceSurface || "api",
|
|
594844
|
+
sessionId: this.opts.sessionId,
|
|
594179
594845
|
scope: this.opts.scope,
|
|
594180
594846
|
sender: this.opts.sender,
|
|
594181
594847
|
message: this.opts.message,
|
|
@@ -594201,7 +594867,7 @@ var init_identity_memory_tool = __esm({
|
|
|
594201
594867
|
} else if (shouldEnrollFace) {
|
|
594202
594868
|
faceLine = "face enrollment: skipped because no resolved image path was available";
|
|
594203
594869
|
}
|
|
594204
|
-
const mediaLine = resolvedMedia ? `media: ${resolvedMedia.label ||
|
|
594870
|
+
const mediaLine = resolvedMedia ? `media: ${resolvedMedia.label || basename21(resolvedMedia.path)} (${resolvedMedia.path})` : "media: none; stored as scoped textual identity evidence only";
|
|
594205
594871
|
const output = [
|
|
594206
594872
|
`Stored identity evidence for ${name10}.`,
|
|
594207
594873
|
`relation: ${relation}`,
|
|
@@ -594222,6 +594888,50 @@ var init_identity_memory_tool = __esm({
|
|
|
594222
594888
|
durationMs: Date.now() - startedAt2
|
|
594223
594889
|
};
|
|
594224
594890
|
}
|
|
594891
|
+
stageIdentity(args, startedAt2) {
|
|
594892
|
+
const name10 = String(args["name"] || "").trim();
|
|
594893
|
+
if (!name10) {
|
|
594894
|
+
return {
|
|
594895
|
+
success: false,
|
|
594896
|
+
output: "",
|
|
594897
|
+
error: "identity_memory stage_identity requires name. Pass the explicit user-provided name for the next visual media.",
|
|
594898
|
+
durationMs: Date.now() - startedAt2
|
|
594899
|
+
};
|
|
594900
|
+
}
|
|
594901
|
+
const evidenceNote = String(args["evidence_note"] ?? args["note"] ?? this.opts.message?.text ?? "").trim();
|
|
594902
|
+
const expiresMinutes = typeof args["expires_in_minutes"] === "number" && Number.isFinite(args["expires_in_minutes"]) ? Math.max(1, Math.min(1440, args["expires_in_minutes"])) : 120;
|
|
594903
|
+
const result = stageVisualIdentityAssertion({
|
|
594904
|
+
repoRoot: this.repoRoot,
|
|
594905
|
+
sourceSurface: this.opts.sourceSurface || "api",
|
|
594906
|
+
sessionId: this.opts.sessionId,
|
|
594907
|
+
scope: this.opts.scope,
|
|
594908
|
+
sender: this.opts.sender,
|
|
594909
|
+
message: this.opts.message,
|
|
594910
|
+
replyTo: this.opts.replyTo,
|
|
594911
|
+
name: name10,
|
|
594912
|
+
relation: "depicts",
|
|
594913
|
+
confidence: coerceConfidence(args["confidence"]),
|
|
594914
|
+
note: evidenceNote || `Explicit user-provided name for the next visual media: ${name10}`,
|
|
594915
|
+
expiresInMs: expiresMinutes * 6e4
|
|
594916
|
+
});
|
|
594917
|
+
return {
|
|
594918
|
+
success: true,
|
|
594919
|
+
output: [
|
|
594920
|
+
`Staged visual identity for next same-scope image: ${result.name}.`,
|
|
594921
|
+
`pending_id: ${result.pendingId}`,
|
|
594922
|
+
`episode: ${result.episodeId}`,
|
|
594923
|
+
`expires_at: ${new Date(result.expiresAt).toISOString()}`
|
|
594924
|
+
].join("\n"),
|
|
594925
|
+
llmContent: [
|
|
594926
|
+
`identity_memory staged next_visual_media name=${result.name}`,
|
|
594927
|
+
`pending_id=${result.pendingId}`,
|
|
594928
|
+
`episode_id=${result.episodeId}`,
|
|
594929
|
+
`expires_at=${new Date(result.expiresAt).toISOString()}`,
|
|
594930
|
+
"When the next image arrives in this same scope, image ingress can link and enroll it without guessing from text."
|
|
594931
|
+
].join("\n"),
|
|
594932
|
+
durationMs: Date.now() - startedAt2
|
|
594933
|
+
};
|
|
594934
|
+
}
|
|
594225
594935
|
async identify(args, startedAt2, graph) {
|
|
594226
594936
|
const resolvedMedia = await resolveMediaFromArgs(args, this.opts);
|
|
594227
594937
|
if (!resolvedMedia?.path) {
|
|
@@ -594240,23 +594950,40 @@ var init_identity_memory_tool = __esm({
|
|
|
594240
594950
|
durationMs: Date.now() - startedAt2
|
|
594241
594951
|
};
|
|
594242
594952
|
}
|
|
594243
|
-
const visual = this.opts.visualMemoryTool ?? new VisualMemoryTool();
|
|
594244
594953
|
const threshold = typeof args["threshold"] === "number" ? args["threshold"] : 0.5;
|
|
594245
|
-
const
|
|
594954
|
+
const association = await associateVisualIdentityFromImage({
|
|
594955
|
+
repoRoot: this.repoRoot,
|
|
594956
|
+
imagePath: resolvedMedia.path,
|
|
594957
|
+
sourceSurface: this.opts.sourceSurface || "api",
|
|
594958
|
+
scope: this.opts.scope,
|
|
594959
|
+
sender: this.opts.sender,
|
|
594960
|
+
message: this.opts.message,
|
|
594961
|
+
replyTo: this.opts.replyTo,
|
|
594962
|
+
sessionId: this.opts.sessionId,
|
|
594963
|
+
media: resolvedMedia.media ?? { path: resolvedMedia.path, mediaType: inferMediaTypeFromPath(resolvedMedia.path) },
|
|
594964
|
+
extractedContent: resolvedMedia.extractedContent,
|
|
594965
|
+
threshold,
|
|
594966
|
+
visualMemoryTool: this.opts.visualMemoryTool,
|
|
594967
|
+
limit: typeof args["limit"] === "number" ? args["limit"] : 5
|
|
594968
|
+
});
|
|
594246
594969
|
const known = graph.nodesByType("person", 50).filter((node) => node.text.startsWith("person:")).map((node) => node.text.slice("person:".length)).slice(0, 12);
|
|
594247
594970
|
const knownLine = known.length ? `known identity nodes: ${known.join(", ")}` : "known identity nodes: none";
|
|
594971
|
+
const matchLine = association.matches.length ? `visual matches: ${association.matches.map((match) => `${match.name} (${match.confidence.toFixed(2)})`).join(", ")}` : "visual matches: none";
|
|
594972
|
+
const context2 = association.contextBlock || association.degradedReason || "No enrolled face matched this image.";
|
|
594248
594973
|
return {
|
|
594249
|
-
success:
|
|
594974
|
+
success: !association.degradedReason,
|
|
594250
594975
|
output: [
|
|
594251
|
-
|
|
594976
|
+
matchLine,
|
|
594977
|
+
context2,
|
|
594252
594978
|
knownLine
|
|
594253
594979
|
].filter(Boolean).join("\n"),
|
|
594254
594980
|
llmContent: [
|
|
594255
|
-
|
|
594981
|
+
matchLine,
|
|
594982
|
+
association.contextBlock || association.degradedReason || "No enrolled face matched this image.",
|
|
594256
594983
|
knownLine,
|
|
594257
594984
|
"If no face matched and the user supplied a name, call identity_memory action='assert_identity'."
|
|
594258
594985
|
].join("\n"),
|
|
594259
|
-
error:
|
|
594986
|
+
error: association.degradedReason,
|
|
594260
594987
|
durationMs: Date.now() - startedAt2
|
|
594261
594988
|
};
|
|
594262
594989
|
}
|
|
@@ -594272,7 +594999,7 @@ ${people.join("\n")}` : "No stored explicit identity nodes found.",
|
|
|
594272
594999
|
durationMs: Date.now() - startedAt2
|
|
594273
595000
|
};
|
|
594274
595001
|
}
|
|
594275
|
-
const node = graph.findNode(
|
|
595002
|
+
const node = graph.findNode(personKey2(name10), "person");
|
|
594276
595003
|
if (!node) {
|
|
594277
595004
|
return {
|
|
594278
595005
|
success: true,
|
|
@@ -595081,7 +595808,7 @@ var init_banner = __esm({
|
|
|
595081
595808
|
|
|
595082
595809
|
// packages/cli/src/tui/carousel-descriptors.ts
|
|
595083
595810
|
import { existsSync as existsSync100, readFileSync as readFileSync80, writeFileSync as writeFileSync51, mkdirSync as mkdirSync57, readdirSync as readdirSync32 } from "node:fs";
|
|
595084
|
-
import { join as join114, basename as
|
|
595811
|
+
import { join as join114, basename as basename22 } from "node:path";
|
|
595085
595812
|
function loadToolProfile(repoRoot) {
|
|
595086
595813
|
const filePath = join114(repoRoot, OMNIUS_DIR, "context", TOOL_PROFILE_FILE);
|
|
595087
595814
|
try {
|
|
@@ -595177,7 +595904,7 @@ function generateDescriptors(repoRoot) {
|
|
|
595177
595904
|
extractFromSessions(repoRoot, tags);
|
|
595178
595905
|
extractFromMemory(repoRoot, tags);
|
|
595179
595906
|
extractFromToolProfile(profile, tags);
|
|
595180
|
-
const repoName2 =
|
|
595907
|
+
const repoName2 = basename22(repoRoot);
|
|
595181
595908
|
if (repoName2 && !tags.includes(repoName2)) {
|
|
595182
595909
|
tags.push(repoName2);
|
|
595183
595910
|
}
|
|
@@ -596197,7 +596924,7 @@ var init_promptLoader3 = __esm({
|
|
|
596197
596924
|
|
|
596198
596925
|
// packages/cli/src/tui/dream-engine.ts
|
|
596199
596926
|
import { mkdirSync as mkdirSync59, writeFileSync as writeFileSync52, readFileSync as readFileSync82, existsSync as existsSync102, readdirSync as readdirSync33 } from "node:fs";
|
|
596200
|
-
import { join as join117, basename as
|
|
596927
|
+
import { join as join117, basename as basename23 } from "node:path";
|
|
596201
596928
|
import { execSync as execSync54 } from "node:child_process";
|
|
596202
596929
|
function setDreamWriteContent(fn) {
|
|
596203
596930
|
_dreamWriteContent = fn;
|
|
@@ -596410,7 +597137,7 @@ var init_dream_engine = __esm({
|
|
|
596410
597137
|
const rawPath = String(args["path"] ?? "");
|
|
596411
597138
|
const content = String(args["content"] ?? "");
|
|
596412
597139
|
if (!rawPath) return { success: false, output: "", error: "path is required", durationMs: Date.now() - start2 };
|
|
596413
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/autoresearch") ? join117(this.autoresearchDir,
|
|
597140
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/autoresearch") ? join117(this.autoresearchDir, basename23(rawPath)) : join117(this.autoresearchDir, rawPath);
|
|
596414
597141
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
596415
597142
|
return { success: false, output: "", error: "Autoresearch mode: writes are confined to .omnius/autoresearch/", durationMs: Date.now() - start2 };
|
|
596416
597143
|
}
|
|
@@ -596445,7 +597172,7 @@ var init_dream_engine = __esm({
|
|
|
596445
597172
|
const rawPath = String(args["path"] ?? "");
|
|
596446
597173
|
const oldStr = String(args["old_string"] ?? "");
|
|
596447
597174
|
const newStr = String(args["new_string"] ?? "");
|
|
596448
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/autoresearch") ? join117(this.autoresearchDir,
|
|
597175
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/autoresearch") ? join117(this.autoresearchDir, basename23(rawPath)) : join117(this.autoresearchDir, rawPath);
|
|
596449
597176
|
if (!targetPath.startsWith(this.autoresearchDir)) {
|
|
596450
597177
|
return { success: false, output: "", error: "Autoresearch mode: edits are confined to .omnius/autoresearch/", durationMs: Date.now() - start2 };
|
|
596451
597178
|
}
|
|
@@ -596498,7 +597225,7 @@ var init_dream_engine = __esm({
|
|
|
596498
597225
|
const rawPath = String(args["path"] ?? "");
|
|
596499
597226
|
const content = String(args["content"] ?? "");
|
|
596500
597227
|
if (!rawPath) return { success: false, output: "", error: "path is required", durationMs: Date.now() - start2 };
|
|
596501
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/dreams") ? join117(this.dreamsDir,
|
|
597228
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/dreams") ? join117(this.dreamsDir, basename23(rawPath)) : join117(this.dreamsDir, rawPath);
|
|
596502
597229
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
596503
597230
|
return { success: false, output: "", error: "Dream mode: writes are confined to .omnius/dreams/", durationMs: Date.now() - start2 };
|
|
596504
597231
|
}
|
|
@@ -596533,7 +597260,7 @@ var init_dream_engine = __esm({
|
|
|
596533
597260
|
const rawPath = String(args["path"] ?? "");
|
|
596534
597261
|
const oldStr = String(args["old_string"] ?? "");
|
|
596535
597262
|
const newStr = String(args["new_string"] ?? "");
|
|
596536
|
-
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/dreams") ? join117(this.dreamsDir,
|
|
597263
|
+
const targetPath = rawPath.startsWith("/") || rawPath.startsWith(".omnius/dreams") ? join117(this.dreamsDir, basename23(rawPath)) : join117(this.dreamsDir, rawPath);
|
|
596537
597264
|
if (!targetPath.startsWith(this.dreamsDir)) {
|
|
596538
597265
|
return { success: false, output: "", error: "Dream mode: edits are confined to .omnius/dreams/", durationMs: Date.now() - start2 };
|
|
596539
597266
|
}
|
|
@@ -598130,7 +598857,7 @@ var init_bless_engine = __esm({
|
|
|
598130
598857
|
|
|
598131
598858
|
// packages/cli/src/tui/dmn-engine.ts
|
|
598132
598859
|
import { existsSync as existsSync103, readFileSync as readFileSync83, writeFileSync as writeFileSync53, mkdirSync as mkdirSync60, readdirSync as readdirSync34, unlinkSync as unlinkSync18 } from "node:fs";
|
|
598133
|
-
import { join as join118, basename as
|
|
598860
|
+
import { join as join118, basename as basename24 } from "node:path";
|
|
598134
598861
|
function buildDMNGatherPrompt(recentTaskSummaries, dueReminders, attentionItems, memoryTopics, capabilities, competence, reflectionBuffer) {
|
|
598135
598862
|
const competenceReport = competence.length > 0 ? competence.map((c9) => {
|
|
598136
598863
|
const rate = c9.attempts > 0 ? Math.round(c9.successes / c9.attempts * 100) : 0;
|
|
@@ -598881,7 +599608,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
598881
599608
|
try {
|
|
598882
599609
|
const files = readdirSync34(dir).filter((f2) => f2.endsWith(".json"));
|
|
598883
599610
|
for (const f2 of files) {
|
|
598884
|
-
const topic =
|
|
599611
|
+
const topic = basename24(f2, ".json");
|
|
598885
599612
|
if (!topics.includes(topic)) topics.push(topic);
|
|
598886
599613
|
}
|
|
598887
599614
|
} catch {
|
|
@@ -598935,7 +599662,7 @@ OUTPUT: Call task_complete with JSON:
|
|
|
598935
599662
|
|
|
598936
599663
|
// packages/cli/src/tui/snr-engine.ts
|
|
598937
599664
|
import { existsSync as existsSync104, readdirSync as readdirSync35, readFileSync as readFileSync84 } from "node:fs";
|
|
598938
|
-
import { join as join119, basename as
|
|
599665
|
+
import { join as join119, basename as basename25 } from "node:path";
|
|
598939
599666
|
function computeDPrime(signalScores, noiseScores) {
|
|
598940
599667
|
if (signalScores.length === 0 || noiseScores.length === 0) return 0;
|
|
598941
599668
|
const mean = (arr) => arr.reduce((s2, v) => s2 + v, 0) / arr.length;
|
|
@@ -599229,7 +599956,7 @@ Call task_complete with the JSON array when done.`,
|
|
|
599229
599956
|
try {
|
|
599230
599957
|
const files = readdirSync35(dir).filter((f2) => f2.endsWith(".json"));
|
|
599231
599958
|
for (const f2 of files) {
|
|
599232
|
-
const topic =
|
|
599959
|
+
const topic = basename25(f2, ".json");
|
|
599233
599960
|
if (topics.length > 0 && !topics.includes(topic)) continue;
|
|
599234
599961
|
try {
|
|
599235
599962
|
const data = JSON.parse(readFileSync84(join119(dir, f2), "utf-8"));
|
|
@@ -599861,7 +600588,7 @@ import {
|
|
|
599861
600588
|
} from "node:fs";
|
|
599862
600589
|
import { mkdir as mkdir17 } from "node:fs/promises";
|
|
599863
600590
|
import {
|
|
599864
|
-
basename as
|
|
600591
|
+
basename as basename26,
|
|
599865
600592
|
dirname as dirname33,
|
|
599866
600593
|
extname as extname15,
|
|
599867
600594
|
isAbsolute as isAbsolute6,
|
|
@@ -600078,7 +600805,7 @@ function guardPath(root, rawPath) {
|
|
|
600078
600805
|
error: `Path escapes the public creative workspace. Use a relative path under ${rootAbs}.`
|
|
600079
600806
|
};
|
|
600080
600807
|
}
|
|
600081
|
-
if (
|
|
600808
|
+
if (basename26(abs) === MANIFEST_FILE) {
|
|
600082
600809
|
return { ok: false, error: "The creative workspace manifest is internal and cannot be edited." };
|
|
600083
600810
|
}
|
|
600084
600811
|
return { ok: true, path: { abs, rel } };
|
|
@@ -600170,7 +600897,7 @@ function rememberCreated(root, absPath) {
|
|
|
600170
600897
|
manifest.objects[rel] = {
|
|
600171
600898
|
logicalRel: rel,
|
|
600172
600899
|
storedRel,
|
|
600173
|
-
originalName:
|
|
600900
|
+
originalName: basename26(guarded.path.abs),
|
|
600174
600901
|
prefixBytes: prefix.length,
|
|
600175
600902
|
encrypted: true,
|
|
600176
600903
|
key: key.toString("base64"),
|
|
@@ -600221,7 +600948,7 @@ function materializeTelegramCreativeArtifactForSend(root, rawPath) {
|
|
|
600221
600948
|
}
|
|
600222
600949
|
const stageDir = join120(rootAbs, SEND_DIR, `${Date.now()}-${randomBytes21(8).toString("hex")}`);
|
|
600223
600950
|
mkdirSync61(stageDir, { recursive: true });
|
|
600224
|
-
const staged = join120(stageDir, object.originalName ||
|
|
600951
|
+
const staged = join120(stageDir, object.originalName || basename26(rel));
|
|
600225
600952
|
writeFileSync54(staged, payload);
|
|
600226
600953
|
return {
|
|
600227
600954
|
ok: true,
|
|
@@ -600437,7 +601164,7 @@ ${result.output}`,
|
|
|
600437
601164
|
});
|
|
600438
601165
|
|
|
600439
601166
|
// packages/cli/src/tui/stimulation.ts
|
|
600440
|
-
function
|
|
601167
|
+
function clamp017(value2) {
|
|
600441
601168
|
return Math.max(0, Math.min(1, value2));
|
|
600442
601169
|
}
|
|
600443
601170
|
function cloneState(state) {
|
|
@@ -600493,7 +601220,7 @@ var init_stimulation = __esm({
|
|
|
600493
601220
|
...DEFAULT_STATE,
|
|
600494
601221
|
...state,
|
|
600495
601222
|
phase: normalizePhase(state.phase) ?? DEFAULT_STATE.phase,
|
|
600496
|
-
attention:
|
|
601223
|
+
attention: clamp017(Number.isFinite(state.attention) ? Number(state.attention) : DEFAULT_STATE.attention),
|
|
600497
601224
|
updatedAtMs: Number.isFinite(state.updatedAtMs) ? Number(state.updatedAtMs) : now,
|
|
600498
601225
|
lastStimulusAtMs: Number.isFinite(state.lastStimulusAtMs) ? Number(state.lastStimulusAtMs) : now,
|
|
600499
601226
|
messagesSinceAnalysis: Math.max(0, Math.floor(Number(state.messagesSinceAnalysis ?? 0))),
|
|
@@ -600543,11 +601270,11 @@ var init_stimulation = __esm({
|
|
|
600543
601270
|
const state = this.stateFor(channelId, nowMs);
|
|
600544
601271
|
this.applyTimeDecay(state, nowMs);
|
|
600545
601272
|
if (Number.isFinite(decision.attentionScore)) {
|
|
600546
|
-
state.attention =
|
|
601273
|
+
state.attention = clamp017(Number(decision.attentionScore));
|
|
600547
601274
|
} else if (Number.isFinite(decision.attentionDelta)) {
|
|
600548
|
-
state.attention =
|
|
601275
|
+
state.attention = clamp017(state.attention + Number(decision.attentionDelta));
|
|
600549
601276
|
} else {
|
|
600550
|
-
state.attention =
|
|
601277
|
+
state.attention = clamp017(state.attention + (decision.shouldReply ? 0.22 : -0.1));
|
|
600551
601278
|
}
|
|
600552
601279
|
if (decision.phase) {
|
|
600553
601280
|
state.attention = Math.max(state.attention, PHASE_FLOORS[decision.phase]);
|
|
@@ -600603,7 +601330,7 @@ var init_stimulation = __esm({
|
|
|
600603
601330
|
const elapsedMs2 = Math.max(0, nowMs - (state.updatedAtMs || nowMs));
|
|
600604
601331
|
if (elapsedMs2 <= 0) return;
|
|
600605
601332
|
const halfLives = elapsedMs2 / (12 * 6e4);
|
|
600606
|
-
state.attention =
|
|
601333
|
+
state.attention = clamp017(state.attention * Math.pow(0.5, halfLives));
|
|
600607
601334
|
if (state.phase !== "engaged" || elapsedMs2 > 4 * 6e4) {
|
|
600608
601335
|
state.phase = phaseFromAttention(state.attention);
|
|
600609
601336
|
}
|
|
@@ -600615,7 +601342,7 @@ var init_stimulation = __esm({
|
|
|
600615
601342
|
// packages/cli/src/tui/telegram-channel-dmn.ts
|
|
600616
601343
|
import { existsSync as existsSync106, mkdirSync as mkdirSync62, readdirSync as readdirSync36, readFileSync as readFileSync86, writeFileSync as writeFileSync55 } from "node:fs";
|
|
600617
601344
|
import { join as join121 } from "node:path";
|
|
600618
|
-
import { createHash as
|
|
601345
|
+
import { createHash as createHash21 } from "node:crypto";
|
|
600619
601346
|
function safeFilePart(value2) {
|
|
600620
601347
|
return value2.replace(/[^A-Za-z0-9_.-]+/g, "_").slice(0, 80) || "telegram";
|
|
600621
601348
|
}
|
|
@@ -600623,12 +601350,12 @@ function daydreamRoot(repoRoot) {
|
|
|
600623
601350
|
return join121(repoRoot, ".omnius", "telegram-daydreams");
|
|
600624
601351
|
}
|
|
600625
601352
|
function sessionDir(repoRoot, sessionKey) {
|
|
600626
|
-
const hash =
|
|
601353
|
+
const hash = createHash21("sha1").update(sessionKey).digest("hex").slice(0, 20);
|
|
600627
601354
|
return join121(daydreamRoot(repoRoot), safeFilePart(hash));
|
|
600628
601355
|
}
|
|
600629
601356
|
function compactLine2(value2, max = 220) {
|
|
600630
|
-
const
|
|
600631
|
-
return
|
|
601357
|
+
const clean5 = value2.replace(/\s+/g, " ").trim();
|
|
601358
|
+
return clean5.length > max ? `${clean5.slice(0, Math.max(0, max - 3)).trimEnd()}...` : clean5;
|
|
600632
601359
|
}
|
|
600633
601360
|
function isoFromMs(value2) {
|
|
600634
601361
|
return value2 ? new Date(value2).toISOString() : void 0;
|
|
@@ -600698,7 +601425,7 @@ function buildReplyOpportunities(input, openQuestions) {
|
|
|
600698
601425
|
}
|
|
600699
601426
|
return opportunities;
|
|
600700
601427
|
}
|
|
600701
|
-
function
|
|
601428
|
+
function clamp018(value2) {
|
|
600702
601429
|
if (!Number.isFinite(value2)) return 0;
|
|
600703
601430
|
return Math.max(0, Math.min(1, value2));
|
|
600704
601431
|
}
|
|
@@ -600709,7 +601436,7 @@ function pushStimulationSignal(signals, signal, source, weight) {
|
|
|
600709
601436
|
const cleanSignal = compactLine2(signal, 120);
|
|
600710
601437
|
const cleanSource = compactLine2(source, 180);
|
|
600711
601438
|
if (!cleanSignal || signals.some((entry) => entry.signal === cleanSignal && entry.source === cleanSource)) return;
|
|
600712
|
-
signals.push({ signal: cleanSignal, source: cleanSource, weight:
|
|
601439
|
+
signals.push({ signal: cleanSignal, source: cleanSource, weight: clamp018(weight) });
|
|
600713
601440
|
}
|
|
600714
601441
|
function buildMetaAnalysisSignals(input) {
|
|
600715
601442
|
const chatLabel = input.chatTitle || input.chatId;
|
|
@@ -600784,7 +601511,7 @@ function buildCuriosityThreads(input, openQuestions, stimulationSignals) {
|
|
|
600784
601511
|
question: text.endsWith("?") || text.endsWith("?") ? text : `What should be learned or clarified from: ${text || entry.mediaSummary || "recent media"}?`,
|
|
600785
601512
|
rationale: "Human curiosity, uncertainty, or multimodal content makes this a useful idle exploration target.",
|
|
600786
601513
|
sourceMessages: messageId,
|
|
600787
|
-
intensity:
|
|
601514
|
+
intensity: clamp018(0.5 + replyBoost + mediaBoost + questionBoost)
|
|
600788
601515
|
});
|
|
600789
601516
|
}
|
|
600790
601517
|
for (const question of openQuestions.slice(-4)) {
|
|
@@ -600804,7 +601531,7 @@ function buildCuriosityThreads(input, openQuestions, stimulationSignals) {
|
|
|
600804
601531
|
question: `Is there a useful clarification or memory consolidation around ${strongest.source}?`,
|
|
600805
601532
|
rationale: "Strongest stimulation signal can seed a low-intrusion reflection target.",
|
|
600806
601533
|
sourceMessages: [],
|
|
600807
|
-
intensity:
|
|
601534
|
+
intensity: clamp018(strongest.weight * 0.72)
|
|
600808
601535
|
});
|
|
600809
601536
|
}
|
|
600810
601537
|
return threads.sort((a2, b) => b.intensity - a2.intensity).slice(0, 8);
|
|
@@ -600864,8 +601591,8 @@ function participantForThread(input, thread) {
|
|
|
600864
601591
|
return input.participants.find((participant) => participant.username === sourceMessage.username);
|
|
600865
601592
|
}
|
|
600866
601593
|
if (sourceMessage?.speaker) {
|
|
600867
|
-
const
|
|
600868
|
-
return input.participants.find((participant) => participant.username ===
|
|
601594
|
+
const clean5 = sourceMessage.speaker.replace(/^@/, "");
|
|
601595
|
+
return input.participants.find((participant) => participant.username === clean5 || participant.firstName === sourceMessage.speaker);
|
|
600869
601596
|
}
|
|
600870
601597
|
return topParticipants(input)[0];
|
|
600871
601598
|
}
|
|
@@ -600878,7 +601605,7 @@ function buildOutreachPlans(input, curiosityThreads) {
|
|
|
600878
601605
|
purpose: "Continue the public thread only when the live model judges that the group would benefit from a concise follow-up.",
|
|
600879
601606
|
draftIntent: "Ask one concrete clarification, offer one useful synthesis, or stay silent if the room has moved on.",
|
|
600880
601607
|
gate: "model_decision",
|
|
600881
|
-
confidence:
|
|
601608
|
+
confidence: clamp018(thread.intensity * 0.86)
|
|
600882
601609
|
});
|
|
600883
601610
|
const participant = participantForThread(input, thread);
|
|
600884
601611
|
if (!participant) continue;
|
|
@@ -600890,7 +601617,7 @@ function buildOutreachPlans(input, curiosityThreads) {
|
|
|
600890
601617
|
purpose: "Offer a one-to-one follow-up only if private contact is allowed and the issue is personal, unresolved, or better handled outside the group.",
|
|
600891
601618
|
draftIntent: "Reference the public thread briefly, ask permission to continue privately, and do not reveal hidden meta-analysis.",
|
|
600892
601619
|
gate: "admin_review",
|
|
600893
|
-
confidence:
|
|
601620
|
+
confidence: clamp018(thread.intensity * 0.58)
|
|
600894
601621
|
});
|
|
600895
601622
|
}
|
|
600896
601623
|
return plans.slice(0, 8);
|
|
@@ -600941,7 +601668,48 @@ function buildMemoryProposals(input) {
|
|
|
600941
601668
|
}
|
|
600942
601669
|
return proposals.slice(0, 6);
|
|
600943
601670
|
}
|
|
600944
|
-
function
|
|
601671
|
+
function corpusPacket(corpus) {
|
|
601672
|
+
return {
|
|
601673
|
+
query: corpus?.query,
|
|
601674
|
+
selectionSeed: corpus?.selectionSeed,
|
|
601675
|
+
stats: corpus?.stats,
|
|
601676
|
+
fallbacks: corpus?.fallbacks ?? [],
|
|
601677
|
+
episodeIds: corpus?.episodeIds ?? [],
|
|
601678
|
+
candidateEpisodeIds: corpus?.candidateEpisodeIds ?? [],
|
|
601679
|
+
selectedEpisodeIds: corpus?.selectedEpisodeIds ?? []
|
|
601680
|
+
};
|
|
601681
|
+
}
|
|
601682
|
+
function selectedSeedPacket(corpus) {
|
|
601683
|
+
const seed = corpus?.graphWalk.seed;
|
|
601684
|
+
if (!seed) return void 0;
|
|
601685
|
+
return {
|
|
601686
|
+
nodeId: seed.node.id,
|
|
601687
|
+
nodeText: seed.node.text,
|
|
601688
|
+
nodeType: seed.node.nodeType,
|
|
601689
|
+
degree: seed.degree,
|
|
601690
|
+
score: seed.score,
|
|
601691
|
+
sourceEpisodeIds: seed.sourceEpisodeIds
|
|
601692
|
+
};
|
|
601693
|
+
}
|
|
601694
|
+
function graphWalkPacket(corpus) {
|
|
601695
|
+
return {
|
|
601696
|
+
visitedNodes: corpus?.graphWalk.visitedNodes.map((node) => ({
|
|
601697
|
+
id: node.id,
|
|
601698
|
+
text: node.text,
|
|
601699
|
+
nodeType: node.nodeType,
|
|
601700
|
+
depth: corpus.graphWalk.depthByNodeId[node.id] ?? 0
|
|
601701
|
+
})) ?? [],
|
|
601702
|
+
traversedEdges: corpus?.graphWalk.traversedEdges.map((edge) => ({
|
|
601703
|
+
id: edge.id,
|
|
601704
|
+
relation: edge.relation,
|
|
601705
|
+
fact: edge.fact,
|
|
601706
|
+
sourceEpisodeId: edge.sourceEpisodeId,
|
|
601707
|
+
confidence: edge.confidence
|
|
601708
|
+
})) ?? [],
|
|
601709
|
+
sourceEpisodeIds: corpus?.graphWalk.sourceEpisodeIds ?? []
|
|
601710
|
+
};
|
|
601711
|
+
}
|
|
601712
|
+
function buildTelegramChannelDaydream(input, corpus, extraction, extractionCommit) {
|
|
600945
601713
|
const firstTs = input.history.map((entry) => entry.ts).find((ts) => typeof ts === "number");
|
|
600946
601714
|
const lastTs = [...input.history].reverse().map((entry) => entry.ts).find((ts) => typeof ts === "number");
|
|
600947
601715
|
const metaAnalysisSignals = buildMetaAnalysisSignals(input);
|
|
@@ -600974,8 +601742,8 @@ function buildTelegramChannelDaydream(input) {
|
|
|
600974
601742
|
].filter((entry) => Boolean(entry));
|
|
600975
601743
|
const seed = `${input.sessionKey}:${input.generatedAtMs}:${input.history.length}`;
|
|
600976
601744
|
return {
|
|
600977
|
-
version:
|
|
600978
|
-
id:
|
|
601745
|
+
version: 3,
|
|
601746
|
+
id: createHash21("sha1").update(seed).digest("hex").slice(0, 16),
|
|
600979
601747
|
sessionKey: input.sessionKey,
|
|
600980
601748
|
chatId: input.chatId,
|
|
600981
601749
|
chatTitle: input.chatTitle,
|
|
@@ -600999,7 +601767,17 @@ function buildTelegramChannelDaydream(input) {
|
|
|
600999
601767
|
memoryProposals,
|
|
601000
601768
|
artifactProposals,
|
|
601001
601769
|
stimulationContext: input.stimulationContext,
|
|
601002
|
-
personaContext: input.personaContext
|
|
601770
|
+
personaContext: input.personaContext,
|
|
601771
|
+
corpus: corpusPacket(corpus),
|
|
601772
|
+
selectedSeed: selectedSeedPacket(corpus),
|
|
601773
|
+
graphWalk: graphWalkPacket(corpus),
|
|
601774
|
+
tagging: extraction?.tags ?? [],
|
|
601775
|
+
summation: extraction?.summaries ?? [],
|
|
601776
|
+
titling: extraction?.titles ?? [],
|
|
601777
|
+
extraction: extraction?.extractions ?? [],
|
|
601778
|
+
linking: extraction?.links ?? [],
|
|
601779
|
+
extractionFollowups: extraction?.followups ?? [],
|
|
601780
|
+
extractionCommit
|
|
601003
601781
|
};
|
|
601004
601782
|
}
|
|
601005
601783
|
function formatTelegramChannelDaydreamMarkdown(artifact) {
|
|
@@ -601010,6 +601788,41 @@ function formatTelegramChannelDaydreamMarkdown(artifact) {
|
|
|
601010
601788
|
`Generated: ${artifact.generatedAt}`,
|
|
601011
601789
|
`Session: ${artifact.sessionKey}`,
|
|
601012
601790
|
`Chat: ${artifact.chatTitle || artifact.chatId} (${artifact.chatType})`,
|
|
601791
|
+
"",
|
|
601792
|
+
"## Reflection Corpus",
|
|
601793
|
+
artifact.corpus.stats ? [
|
|
601794
|
+
`- retained messages: ${artifact.corpus.stats.retainedMessages}`,
|
|
601795
|
+
`- candidate episodes: ${artifact.corpus.stats.candidateEpisodes}`,
|
|
601796
|
+
`- selected episodes: ${artifact.corpus.stats.selectedEpisodes}`,
|
|
601797
|
+
`- vector search limit: ${artifact.corpus.stats.vectorSearchLimitUsed}`,
|
|
601798
|
+
`- graph walk: ${artifact.corpus.stats.graphNodesVisited} node(s), ${artifact.corpus.stats.graphEdgesTraversed} edge(s)`,
|
|
601799
|
+
artifact.corpus.fallbacks.length ? `- fallbacks: ${artifact.corpus.fallbacks.join("; ")}` : "- fallbacks: none"
|
|
601800
|
+
].join("\n") : "- Not available",
|
|
601801
|
+
artifact.selectedSeed ? `
|
|
601802
|
+
Selected seed: ${artifact.selectedSeed.nodeText} (${artifact.selectedSeed.nodeType}, degree ${artifact.selectedSeed.degree})` : "",
|
|
601803
|
+
"",
|
|
601804
|
+
"## Tags",
|
|
601805
|
+
artifact.tagging.length ? artifact.tagging.map((item) => `- ${item.label} [${item.kind}] confidence=${item.confidence.toFixed(2)}${item.sourceMessageIds.length ? ` messages=${item.sourceMessageIds.join(", ")}` : ""}`).join("\n") : "- None",
|
|
601806
|
+
"",
|
|
601807
|
+
"## Summaries",
|
|
601808
|
+
artifact.summation.length ? artifact.summation.map((item) => `- ${item.title} [${item.scope}] confidence=${item.confidence.toFixed(2)}
|
|
601809
|
+
${item.text}${item.sourceMessageIds.length ? `
|
|
601810
|
+
messages=${item.sourceMessageIds.join(", ")}` : ""}`).join("\n") : "- None",
|
|
601811
|
+
"",
|
|
601812
|
+
"## Titles",
|
|
601813
|
+
artifact.titling.length ? artifact.titling.map((item) => `- ${item.title} -> ${item.target} confidence=${item.confidence.toFixed(2)}`).join("\n") : "- None",
|
|
601814
|
+
"",
|
|
601815
|
+
"## Extractions",
|
|
601816
|
+
artifact.extraction.length ? artifact.extraction.map((item) => `- ${item.kind}: ${item.text} confidence=${item.confidence.toFixed(2)}${item.sourceMessageIds.length ? ` messages=${item.sourceMessageIds.join(", ")}` : ""}`).join("\n") : "- None",
|
|
601817
|
+
"",
|
|
601818
|
+
"## Links",
|
|
601819
|
+
artifact.linking.length ? artifact.linking.map((item) => `- ${item.srcNodeText} --${item.relation}--> ${item.dstNodeText} confidence=${item.confidence.toFixed(2)}
|
|
601820
|
+
${item.fact}${item.sourceMessageIds.length ? `
|
|
601821
|
+
messages=${item.sourceMessageIds.join(", ")}` : ""}`).join("\n") : "- None",
|
|
601822
|
+
"",
|
|
601823
|
+
"## Extraction Followups",
|
|
601824
|
+
artifact.extractionFollowups.length ? artifact.extractionFollowups.map((item) => `- ${item.target}${item.replyToMessageId ? ` reply_to=${item.replyToMessageId}` : ""} confidence=${item.confidence.toFixed(2)}
|
|
601825
|
+
${item.text || item.rationale}`).join("\n") : "- None",
|
|
601013
601826
|
"",
|
|
601014
601827
|
section("Meta-Analysis Signals", artifact.metaAnalysisSignals),
|
|
601015
601828
|
"",
|
|
@@ -601099,6 +601912,18 @@ function formatTelegramChannelDaydreamContext(artifact) {
|
|
|
601099
601912
|
"### Telegram Channel Daydream",
|
|
601100
601913
|
"Private idle reflection and stimulation artifact. Use it as context only; do not mention it unless the user asks about internal memory.",
|
|
601101
601914
|
`Generated: ${artifact.generatedAt}`,
|
|
601915
|
+
artifact.corpus?.stats ? `Corpus: ${artifact.corpus.stats.selectedEpisodes} selected episode(s), ${artifact.corpus.stats.graphNodesVisited} graph node(s), search limit ${artifact.corpus.stats.vectorSearchLimitUsed}` : "",
|
|
601916
|
+
artifact.selectedSeed ? `Selected seed: ${artifact.selectedSeed.nodeText} (degree ${artifact.selectedSeed.degree})` : "",
|
|
601917
|
+
artifact.tagging?.length ? `Tags:
|
|
601918
|
+
${artifact.tagging.slice(0, 8).map((item) => `- ${item.label} [${item.kind}] (${item.confidence.toFixed(2)})`).join("\n")}` : "",
|
|
601919
|
+
artifact.summation?.length ? `Summaries:
|
|
601920
|
+
${artifact.summation.slice(0, 4).map((item) => `- ${item.title}: ${item.text}`).join("\n")}` : "",
|
|
601921
|
+
artifact.extraction?.length ? `Extracted items:
|
|
601922
|
+
${artifact.extraction.slice(0, 6).map((item) => `- ${item.kind}: ${item.text}${item.sourceMessageIds.length ? ` (messages ${item.sourceMessageIds.join(", ")})` : ""}`).join("\n")}` : "",
|
|
601923
|
+
artifact.linking?.length ? `Graph links:
|
|
601924
|
+
${artifact.linking.slice(0, 5).map((item) => `- ${item.srcNodeText} --${item.relation}--> ${item.dstNodeText}`).join("\n")}` : "",
|
|
601925
|
+
artifact.extractionFollowups?.length ? `Extraction followups:
|
|
601926
|
+
${artifact.extractionFollowups.slice(0, 4).map((item) => `- ${item.target}${item.replyToMessageId ? ` reply_to=${item.replyToMessageId}` : ""}: ${item.text || item.rationale}`).join("\n")}` : "",
|
|
601102
601927
|
artifact.metaAnalysisSignals?.length ? `Meta-analysis signals:
|
|
601103
601928
|
${artifact.metaAnalysisSignals.slice(0, 4).map((line) => `- ${line}`).join("\n")}` : "",
|
|
601104
601929
|
artifact.humanStimulationSignals?.length ? `Human stimulation signals:
|
|
@@ -601128,6 +601953,715 @@ var init_telegram_channel_dmn = __esm({
|
|
|
601128
601953
|
}
|
|
601129
601954
|
});
|
|
601130
601955
|
|
|
601956
|
+
// packages/cli/src/tui/telegram-reflection-corpus.ts
|
|
601957
|
+
import { createHash as createHash22 } from "node:crypto";
|
|
601958
|
+
function telegramReflectionMemoryDbPaths(repoRoot) {
|
|
601959
|
+
return omniusMemoryDbPaths(repoRoot);
|
|
601960
|
+
}
|
|
601961
|
+
function stableHash2(value2, length4 = 16) {
|
|
601962
|
+
return createHash22("sha1").update(value2).digest("hex").slice(0, length4);
|
|
601963
|
+
}
|
|
601964
|
+
function clean3(value2) {
|
|
601965
|
+
return String(value2 ?? "").replace(/\s+/g, " ").trim();
|
|
601966
|
+
}
|
|
601967
|
+
function compact(value2, max = 420) {
|
|
601968
|
+
const text = clean3(value2);
|
|
601969
|
+
return text.length > max ? `${text.slice(0, Math.max(0, max - 3)).trimEnd()}...` : text;
|
|
601970
|
+
}
|
|
601971
|
+
function senderLabel(entry) {
|
|
601972
|
+
if (entry.role === "assistant") return entry.speaker || "Assistant";
|
|
601973
|
+
if (entry.speaker) return entry.speaker;
|
|
601974
|
+
if (entry.username) return `@${entry.username}`;
|
|
601975
|
+
if (entry.firstName) return entry.firstName;
|
|
601976
|
+
if (entry.fromUserId) return `user:${entry.fromUserId}`;
|
|
601977
|
+
return "Telegram user";
|
|
601978
|
+
}
|
|
601979
|
+
function senderKey2(entry) {
|
|
601980
|
+
if (entry.role === "assistant") return entry.username || entry.speaker || "assistant";
|
|
601981
|
+
return String(entry.fromUserId || entry.username || entry.firstName || senderLabel(entry));
|
|
601982
|
+
}
|
|
601983
|
+
function scopeFor(entry, options2) {
|
|
601984
|
+
const chatType = entry.chatType || options2.chatType || "unknown";
|
|
601985
|
+
return {
|
|
601986
|
+
kind: `telegram-${chatType}`,
|
|
601987
|
+
id: String(entry.chatId ?? options2.chatId),
|
|
601988
|
+
title: entry.chatTitle || options2.chatTitle
|
|
601989
|
+
};
|
|
601990
|
+
}
|
|
601991
|
+
function senderFor(entry) {
|
|
601992
|
+
return {
|
|
601993
|
+
id: senderKey2(entry),
|
|
601994
|
+
username: entry.username,
|
|
601995
|
+
displayName: senderLabel(entry),
|
|
601996
|
+
isBot: entry.role === "assistant"
|
|
601997
|
+
};
|
|
601998
|
+
}
|
|
601999
|
+
function messageIdFor(entry, sessionKey) {
|
|
602000
|
+
if (typeof entry.messageId === "number" && Number.isFinite(entry.messageId)) return entry.messageId;
|
|
602001
|
+
return stableHash2(`${sessionKey}:${entry.role}:${entry.ts ?? ""}:${senderLabel(entry)}:${entry.text}`);
|
|
602002
|
+
}
|
|
602003
|
+
function messageRefFor(entry, sessionKey) {
|
|
602004
|
+
return {
|
|
602005
|
+
id: messageIdFor(entry, sessionKey),
|
|
602006
|
+
threadId: entry.messageThreadId,
|
|
602007
|
+
timestamp: entry.ts,
|
|
602008
|
+
text: entry.text
|
|
602009
|
+
};
|
|
602010
|
+
}
|
|
602011
|
+
function replyRefFor(entry) {
|
|
602012
|
+
const reply = entry.replyContext;
|
|
602013
|
+
const replyId = reply?.messageId ?? entry.replyToMessageId;
|
|
602014
|
+
if (replyId == null) return void 0;
|
|
602015
|
+
return {
|
|
602016
|
+
id: replyId,
|
|
602017
|
+
threadId: reply?.threadId,
|
|
602018
|
+
text: reply?.text || reply?.caption || reply?.mediaSummary,
|
|
602019
|
+
sender: reply?.sender ? {
|
|
602020
|
+
id: reply.sender.id == null ? void 0 : String(reply.sender.id),
|
|
602021
|
+
username: reply.sender.username,
|
|
602022
|
+
displayName: reply.sender.title || reply.sender.firstName || reply.sender.username,
|
|
602023
|
+
isBot: reply.sender.isBot
|
|
602024
|
+
} : void 0
|
|
602025
|
+
};
|
|
602026
|
+
}
|
|
602027
|
+
function contentFor(entry, sessionKey, options2) {
|
|
602028
|
+
const lines = [
|
|
602029
|
+
`Telegram ${entry.chatType || options2.chatType || "unknown"} ${entry.role} message`,
|
|
602030
|
+
`session: ${sessionKey}`,
|
|
602031
|
+
`chat: ${entry.chatTitle || options2.chatTitle || entry.chatId || options2.chatId}`,
|
|
602032
|
+
`message_id: ${messageIdFor(entry, sessionKey)}`,
|
|
602033
|
+
entry.messageThreadId != null ? `thread_id: ${entry.messageThreadId}` : "",
|
|
602034
|
+
entry.replyToMessageId != null ? `reply_to_message_id: ${entry.replyToMessageId}` : "",
|
|
602035
|
+
`speaker: ${senderLabel(entry)}`,
|
|
602036
|
+
entry.mode ? `mode: ${entry.mode}` : "",
|
|
602037
|
+
entry.mediaSummary ? `media: ${compact(entry.mediaSummary, 260)}` : "",
|
|
602038
|
+
"",
|
|
602039
|
+
entry.text
|
|
602040
|
+
].filter((line) => line !== "");
|
|
602041
|
+
return lines.join("\n");
|
|
602042
|
+
}
|
|
602043
|
+
function metadataFor(entry, sessionKey, options2) {
|
|
602044
|
+
return {
|
|
602045
|
+
sourceSurface: "telegram",
|
|
602046
|
+
sessionKey,
|
|
602047
|
+
telegram: {
|
|
602048
|
+
role: entry.role,
|
|
602049
|
+
mode: entry.mode,
|
|
602050
|
+
chatId: String(entry.chatId ?? options2.chatId),
|
|
602051
|
+
chatType: entry.chatType || options2.chatType,
|
|
602052
|
+
chatTitle: entry.chatTitle || options2.chatTitle,
|
|
602053
|
+
messageId: entry.messageId,
|
|
602054
|
+
messageThreadId: entry.messageThreadId,
|
|
602055
|
+
replyToMessageId: entry.replyToMessageId,
|
|
602056
|
+
username: entry.username,
|
|
602057
|
+
firstName: entry.firstName,
|
|
602058
|
+
fromUserId: entry.fromUserId,
|
|
602059
|
+
speaker: senderLabel(entry),
|
|
602060
|
+
mediaSummary: entry.mediaSummary
|
|
602061
|
+
}
|
|
602062
|
+
};
|
|
602063
|
+
}
|
|
602064
|
+
function graphTopicNode(graph, label) {
|
|
602065
|
+
return graph.upsertNode({ text: `topic:${label}`, nodeType: "concept" });
|
|
602066
|
+
}
|
|
602067
|
+
function addTextEdges(graph, result, entry) {
|
|
602068
|
+
const messageId = result.nodeIds.message;
|
|
602069
|
+
const senderId = result.nodeIds.sender;
|
|
602070
|
+
if (messageId && senderId) {
|
|
602071
|
+
graph.addEdge({
|
|
602072
|
+
srcId: messageId,
|
|
602073
|
+
dstId: senderId,
|
|
602074
|
+
relation: "said_by",
|
|
602075
|
+
fact: compact(entry.text, 260),
|
|
602076
|
+
sourceEpisodeId: result.episodeId,
|
|
602077
|
+
modality: entry.role === "user" ? "social" : "text",
|
|
602078
|
+
confidence: entry.role === "assistant" ? 0.92 : 0.96
|
|
602079
|
+
});
|
|
602080
|
+
}
|
|
602081
|
+
if (messageId) {
|
|
602082
|
+
const channelTopic = graphTopicNode(graph, "telegram-reflection-corpus");
|
|
602083
|
+
graph.addEdge({
|
|
602084
|
+
srcId: messageId,
|
|
602085
|
+
dstId: channelTopic,
|
|
602086
|
+
relation: "related_to",
|
|
602087
|
+
fact: compact(entry.text || entry.mediaSummary || "telegram message", 220),
|
|
602088
|
+
sourceEpisodeId: result.episodeId,
|
|
602089
|
+
modality: entry.role === "user" ? "social" : "text",
|
|
602090
|
+
confidence: 0.72
|
|
602091
|
+
});
|
|
602092
|
+
}
|
|
602093
|
+
}
|
|
602094
|
+
function upsertTelegramReflectionMessage(repoRoot, sessionKey, entry, options2) {
|
|
602095
|
+
const paths = telegramReflectionMemoryDbPaths(repoRoot);
|
|
602096
|
+
const graph = new TemporalGraph(paths.knowledge);
|
|
602097
|
+
const store2 = new EpisodeStore(paths.episodes, graph);
|
|
602098
|
+
try {
|
|
602099
|
+
const before = store2.count(sessionKey);
|
|
602100
|
+
const service = new MultimodalIdentityService({ episodeStore: store2, graph });
|
|
602101
|
+
const content = contentFor(entry, sessionKey, options2);
|
|
602102
|
+
const result = service.ingest({
|
|
602103
|
+
sourceSurface: "telegram",
|
|
602104
|
+
sessionId: sessionKey,
|
|
602105
|
+
metadata: metadataFor(entry, sessionKey, options2),
|
|
602106
|
+
scope: scopeFor(entry, options2),
|
|
602107
|
+
sender: senderFor(entry),
|
|
602108
|
+
message: messageRefFor(entry, sessionKey),
|
|
602109
|
+
replyTo: replyRefFor(entry),
|
|
602110
|
+
modality: entry.role === "user" ? "social" : "text",
|
|
602111
|
+
content,
|
|
602112
|
+
labels: [entry.mode, entry.mediaSummary, senderLabel(entry)].filter((value2) => Boolean(value2))
|
|
602113
|
+
});
|
|
602114
|
+
addTextEdges(graph, result, entry);
|
|
602115
|
+
const after = store2.count(sessionKey);
|
|
602116
|
+
return { episodeId: result.episodeId, reused: after === before };
|
|
602117
|
+
} finally {
|
|
602118
|
+
store2.close();
|
|
602119
|
+
graph.close();
|
|
602120
|
+
}
|
|
602121
|
+
}
|
|
602122
|
+
function queryFor(options2) {
|
|
602123
|
+
if (options2.query?.trim()) return options2.query.trim();
|
|
602124
|
+
const recent = options2.history.slice(-12).map((entry) => compact(`${senderLabel(entry)}: ${entry.text || entry.mediaSummary || ""}`, 180));
|
|
602125
|
+
return [
|
|
602126
|
+
`Telegram ${options2.chatType} ${options2.chatTitle || options2.chatId} reflection`,
|
|
602127
|
+
...recent
|
|
602128
|
+
].filter(Boolean).join("\n");
|
|
602129
|
+
}
|
|
602130
|
+
async function fillMissingEmbeddings(store2, graph, episodes, embeddingConfig) {
|
|
602131
|
+
if (embeddingConfig === false) return { embedded: 0, unavailable: true, queryEmbedding: null };
|
|
602132
|
+
const missing = episodes.filter((episode) => !episode.embedding && episode.content.trim());
|
|
602133
|
+
if (missing.length === 0) return { embedded: 0, unavailable: false, queryEmbedding: null };
|
|
602134
|
+
const results = await generateEmbeddingBatch(missing.map((episode) => episode.content.slice(0, 4e3)), embeddingConfig);
|
|
602135
|
+
let embedded = 0;
|
|
602136
|
+
for (let i2 = 0; i2 < missing.length; i2++) {
|
|
602137
|
+
const result = results[i2];
|
|
602138
|
+
const episode = missing[i2];
|
|
602139
|
+
if (!result || !episode) continue;
|
|
602140
|
+
store2.setEmbedding(episode.id, result.vector);
|
|
602141
|
+
const refreshed = store2.get(episode.id);
|
|
602142
|
+
if (refreshed) linkEpisode(refreshed, store2, graph);
|
|
602143
|
+
embedded++;
|
|
602144
|
+
}
|
|
602145
|
+
return { embedded, unavailable: embedded === 0 && missing.length > 0, queryEmbedding: null };
|
|
602146
|
+
}
|
|
602147
|
+
async function queryEmbeddingFor(query, embeddingConfig) {
|
|
602148
|
+
if (embeddingConfig === false) return null;
|
|
602149
|
+
const result = await generateEmbedding(query.slice(0, 4e3), embeddingConfig);
|
|
602150
|
+
return result?.vector ?? null;
|
|
602151
|
+
}
|
|
602152
|
+
async function buildTelegramReflectionCorpus(options2) {
|
|
602153
|
+
const paths = telegramReflectionMemoryDbPaths(options2.repoRoot);
|
|
602154
|
+
const graph = new TemporalGraph(paths.knowledge);
|
|
602155
|
+
const store2 = new EpisodeStore(paths.episodes, graph);
|
|
602156
|
+
const episodeIds = [];
|
|
602157
|
+
let reusedEpisodes = 0;
|
|
602158
|
+
const fallbacks = [];
|
|
602159
|
+
try {
|
|
602160
|
+
const service = new MultimodalIdentityService({ episodeStore: store2, graph });
|
|
602161
|
+
for (const entry of options2.history) {
|
|
602162
|
+
const before = store2.count(options2.sessionKey);
|
|
602163
|
+
const content = contentFor(entry, options2.sessionKey, options2);
|
|
602164
|
+
const result = service.ingest({
|
|
602165
|
+
sourceSurface: "telegram",
|
|
602166
|
+
sessionId: options2.sessionKey,
|
|
602167
|
+
metadata: metadataFor(entry, options2.sessionKey, options2),
|
|
602168
|
+
scope: scopeFor(entry, options2),
|
|
602169
|
+
sender: senderFor(entry),
|
|
602170
|
+
message: messageRefFor(entry, options2.sessionKey),
|
|
602171
|
+
replyTo: replyRefFor(entry),
|
|
602172
|
+
modality: entry.role === "user" ? "social" : "text",
|
|
602173
|
+
content,
|
|
602174
|
+
labels: [entry.mode, entry.mediaSummary, senderLabel(entry)].filter((value2) => Boolean(value2))
|
|
602175
|
+
});
|
|
602176
|
+
addTextEdges(graph, result, entry);
|
|
602177
|
+
const after = store2.count(options2.sessionKey);
|
|
602178
|
+
if (after === before) reusedEpisodes++;
|
|
602179
|
+
if (result.episodeId) episodeIds.push(result.episodeId);
|
|
602180
|
+
}
|
|
602181
|
+
const scopedEpisodes = store2.recent(500, options2.sessionKey).filter((episode) => {
|
|
602182
|
+
const meta = episode.metadata;
|
|
602183
|
+
return meta?.sourceSurface === "telegram" || meta?.telegram && typeof meta.telegram === "object";
|
|
602184
|
+
});
|
|
602185
|
+
const embeddingFill = await fillMissingEmbeddings(store2, graph, scopedEpisodes, options2.embeddingConfig);
|
|
602186
|
+
const query = queryFor(options2);
|
|
602187
|
+
const queryEmbedding = await queryEmbeddingFor(query, options2.embeddingConfig);
|
|
602188
|
+
if (embeddingFill.unavailable || !queryEmbedding) fallbacks.push("embedding unavailable or incomplete; lexical scoped search included");
|
|
602189
|
+
let graphWalk = null;
|
|
602190
|
+
let selectedEpisodes = [];
|
|
602191
|
+
let vectorSearchLimitUsed = 0;
|
|
602192
|
+
let candidateEpisodes = [];
|
|
602193
|
+
const limits = options2.candidateLimits ?? [48, 96, 192, 384, 500];
|
|
602194
|
+
for (const limit of limits) {
|
|
602195
|
+
vectorSearchLimitUsed = limit;
|
|
602196
|
+
candidateEpisodes = store2.search(
|
|
602197
|
+
{
|
|
602198
|
+
sessionId: options2.sessionKey,
|
|
602199
|
+
query,
|
|
602200
|
+
limit,
|
|
602201
|
+
metadataFilter: { sourceSurface: "telegram" }
|
|
602202
|
+
},
|
|
602203
|
+
{
|
|
602204
|
+
queryEmbedding,
|
|
602205
|
+
lexicalWeight: 1,
|
|
602206
|
+
embeddingWeight: queryEmbedding ? 1.8 : 0
|
|
602207
|
+
}
|
|
602208
|
+
);
|
|
602209
|
+
graphWalk = selectAndWalkGraphCandidate(
|
|
602210
|
+
graph,
|
|
602211
|
+
candidateEpisodes.map((episode, index) => ({ episode, score: limit - index })),
|
|
602212
|
+
{
|
|
602213
|
+
seed: `${options2.sessionKey}:${options2.generatedAtMs}:${limit}`,
|
|
602214
|
+
maxDepth: 2,
|
|
602215
|
+
maxVisitedNodes: 72,
|
|
602216
|
+
maxTraversedEdges: 180,
|
|
602217
|
+
maxSourceEpisodes: 100
|
|
602218
|
+
}
|
|
602219
|
+
);
|
|
602220
|
+
if (graphWalk.seed) {
|
|
602221
|
+
selectedEpisodes = graphWalk.sourceEpisodeIds.map((id) => store2.get(id)).filter((episode) => Boolean(episode));
|
|
602222
|
+
if (selectedEpisodes.length < (options2.minWalkEpisodes ?? 8)) {
|
|
602223
|
+
const deeper = selectAndWalkGraphCandidate(
|
|
602224
|
+
graph,
|
|
602225
|
+
candidateEpisodes.map((episode, index) => ({ episode, score: limit - index })),
|
|
602226
|
+
{
|
|
602227
|
+
seed: `${options2.sessionKey}:${options2.generatedAtMs}:${limit}:deep`,
|
|
602228
|
+
maxDepth: 3,
|
|
602229
|
+
maxVisitedNodes: 96,
|
|
602230
|
+
maxTraversedEdges: 240,
|
|
602231
|
+
maxSourceEpisodes: 120
|
|
602232
|
+
}
|
|
602233
|
+
);
|
|
602234
|
+
if (deeper.seed && deeper.sourceEpisodeIds.length >= graphWalk.sourceEpisodeIds.length) graphWalk = deeper;
|
|
602235
|
+
}
|
|
602236
|
+
selectedEpisodes = graphWalk.sourceEpisodeIds.map((id) => store2.get(id)).filter((episode) => Boolean(episode));
|
|
602237
|
+
break;
|
|
602238
|
+
}
|
|
602239
|
+
}
|
|
602240
|
+
if (!graphWalk) {
|
|
602241
|
+
graphWalk = selectAndWalkGraphCandidate(graph, [], { seed: `${options2.sessionKey}:${options2.generatedAtMs}:empty` });
|
|
602242
|
+
}
|
|
602243
|
+
if (!graphWalk.seed && graphWalk.fallbackReason) fallbacks.push(graphWalk.fallbackReason);
|
|
602244
|
+
if (selectedEpisodes.length === 0) {
|
|
602245
|
+
selectedEpisodes = candidateEpisodes.slice(0, Math.min(24, candidateEpisodes.length));
|
|
602246
|
+
if (selectedEpisodes.length > 0) fallbacks.push("selected recent scoped episodes because graph walk produced no source episode anchors");
|
|
602247
|
+
}
|
|
602248
|
+
return {
|
|
602249
|
+
stats: {
|
|
602250
|
+
retainedMessages: options2.history.length,
|
|
602251
|
+
upsertedEpisodes: episodeIds.length,
|
|
602252
|
+
reusedEpisodes,
|
|
602253
|
+
embeddedEpisodes: embeddingFill.embedded,
|
|
602254
|
+
candidateEpisodes: candidateEpisodes.length,
|
|
602255
|
+
selectedEpisodes: selectedEpisodes.length,
|
|
602256
|
+
graphNodesVisited: graphWalk.visitedNodes.length,
|
|
602257
|
+
graphEdgesTraversed: graphWalk.traversedEdges.length,
|
|
602258
|
+
vectorSearchLimitUsed,
|
|
602259
|
+
embeddingUnavailable: embeddingFill.unavailable || !queryEmbedding
|
|
602260
|
+
},
|
|
602261
|
+
episodeIds: [...new Set(episodeIds)],
|
|
602262
|
+
candidateEpisodeIds: candidateEpisodes.map((episode) => episode.id),
|
|
602263
|
+
selectedEpisodeIds: selectedEpisodes.map((episode) => episode.id),
|
|
602264
|
+
selectedEpisodes,
|
|
602265
|
+
graphWalk,
|
|
602266
|
+
selectionSeed: `${options2.sessionKey}:${options2.generatedAtMs}:${vectorSearchLimitUsed}`,
|
|
602267
|
+
query,
|
|
602268
|
+
fallbacks
|
|
602269
|
+
};
|
|
602270
|
+
} finally {
|
|
602271
|
+
store2.close();
|
|
602272
|
+
graph.close();
|
|
602273
|
+
}
|
|
602274
|
+
}
|
|
602275
|
+
var init_telegram_reflection_corpus = __esm({
|
|
602276
|
+
"packages/cli/src/tui/telegram-reflection-corpus.ts"() {
|
|
602277
|
+
"use strict";
|
|
602278
|
+
init_dist7();
|
|
602279
|
+
init_memory_paths();
|
|
602280
|
+
}
|
|
602281
|
+
});
|
|
602282
|
+
|
|
602283
|
+
// packages/cli/src/tui/telegram-reflection-extraction.ts
|
|
602284
|
+
function clean4(value2, max = 2e3) {
|
|
602285
|
+
const text = String(value2 ?? "").replace(/\s+/g, " ").trim();
|
|
602286
|
+
return text.length > max ? `${text.slice(0, Math.max(0, max - 3)).trimEnd()}...` : text;
|
|
602287
|
+
}
|
|
602288
|
+
function clampConfidence(value2, fallback = 0.5) {
|
|
602289
|
+
if (typeof value2 !== "number" || !Number.isFinite(value2)) return fallback;
|
|
602290
|
+
return Math.max(0, Math.min(1, value2));
|
|
602291
|
+
}
|
|
602292
|
+
function numberArray(value2) {
|
|
602293
|
+
if (!Array.isArray(value2)) return [];
|
|
602294
|
+
return [...new Set(value2.map((item) => Number(item)).filter((item) => Number.isFinite(item)).map((item) => Math.trunc(item)))];
|
|
602295
|
+
}
|
|
602296
|
+
function stringArray(value2) {
|
|
602297
|
+
if (!Array.isArray(value2)) return [];
|
|
602298
|
+
return [...new Set(value2.map((item) => clean4(item, 180)).filter(Boolean))];
|
|
602299
|
+
}
|
|
602300
|
+
function episodeLine(episode) {
|
|
602301
|
+
const meta = episode.metadata;
|
|
602302
|
+
const telegram = meta?.telegram;
|
|
602303
|
+
const speaker = clean4(telegram?.speaker || telegram?.username || "unknown", 80);
|
|
602304
|
+
const messageId = telegram?.messageId == null ? "unknown" : String(telegram.messageId);
|
|
602305
|
+
const replyTo = telegram?.replyToMessageId == null ? "" : ` reply_to=${telegram.replyToMessageId}`;
|
|
602306
|
+
return [
|
|
602307
|
+
`episode_id=${episode.id}`,
|
|
602308
|
+
`message_id=${messageId}${replyTo}`,
|
|
602309
|
+
`speaker=${speaker}`,
|
|
602310
|
+
`modality=${episode.modality}`,
|
|
602311
|
+
`content=${clean4(episode.content, 700)}`
|
|
602312
|
+
].join(" | ");
|
|
602313
|
+
}
|
|
602314
|
+
function buildTelegramReflectionExtractionPrompt(options2) {
|
|
602315
|
+
const corpus = options2.corpus;
|
|
602316
|
+
const walkNodes = corpus.graphWalk.visitedNodes.slice(0, 40).map((node) => `node_id=${node.id} type=${node.nodeType} mentions=${node.mentionCount} text=${clean4(node.text, 220)}`).join("\n");
|
|
602317
|
+
const walkEdges = corpus.graphWalk.traversedEdges.slice(0, 60).map((edge) => `edge_id=${edge.id} relation=${edge.relation} confidence=${edge.confidence.toFixed(2)} src=${edge.srcId} dst=${edge.dstId} source_episode=${edge.sourceEpisodeId || "none"} fact=${clean4(edge.fact, 220)}`).join("\n");
|
|
602318
|
+
const episodes = corpus.selectedEpisodes.slice(0, 36).map(episodeLine).join("\n");
|
|
602319
|
+
return [
|
|
602320
|
+
"You are extracting a reusable Telegram reflection artifact from a scoped chat corpus.",
|
|
602321
|
+
"Return strict JSON only. Do not include Markdown, prose, or comments.",
|
|
602322
|
+
"",
|
|
602323
|
+
"Required top-level JSON keys:",
|
|
602324
|
+
"artifact_title, tags, summaries, titles, extractions, links, followups",
|
|
602325
|
+
"",
|
|
602326
|
+
"Rules:",
|
|
602327
|
+
"- Use only the scoped Telegram corpus, graph nodes, graph edges, and source anchors below.",
|
|
602328
|
+
"- Preserve message_id and episode_id anchors on every item when possible.",
|
|
602329
|
+
"- Do not infer identity from a face, voice, or name unless the corpus explicitly says it.",
|
|
602330
|
+
"- Private DM followups may be proposed but must not be framed as already sent.",
|
|
602331
|
+
"- same_group followups must be concise, low-intrusion, and anchored to a source message id.",
|
|
602332
|
+
"- If a category has no evidence, return an empty array for that category.",
|
|
602333
|
+
"",
|
|
602334
|
+
"Schema:",
|
|
602335
|
+
JSON.stringify({
|
|
602336
|
+
artifact_title: "short title",
|
|
602337
|
+
tags: [{ label: "tag", kind: "topic|person|preference|task|media|tone", confidence: 0, source_message_ids: [1], target_episode_ids: ["episode-id"], target_node_ids: ["node-id"] }],
|
|
602338
|
+
summaries: [{ title: "summary title", scope: "channel|thread|participant|message_window", text: "summary text", confidence: 0, source_message_ids: [1], target_episode_ids: ["episode-id"] }],
|
|
602339
|
+
titles: [{ title: "usable title", target: "artifact|thread|memory_card|graph_node", confidence: 0, source_message_ids: [1], target_episode_ids: ["episode-id"] }],
|
|
602340
|
+
extractions: [{ kind: "fact|preference|open_question|decision|identity_candidate|media_reference|followup_need", text: "extracted item", confidence: 0, source_message_ids: [1], target_episode_ids: ["episode-id"], target_node_ids: ["node-id"] }],
|
|
602341
|
+
links: [{ relation: "related_to|contains|authored_by|replied_to|said_by|depicts|named_as|same_person_candidate", src_node_text: "node text", dst_node_text: "node text", confidence: 0, fact: "why linked", source_message_ids: [1], target_episode_ids: ["episode-id"] }],
|
|
602342
|
+
followups: [{ target: "same_group|private_dm|none", text: "candidate visible reply", reply_to_message_id: 1, rationale: "why", confidence: 0 }]
|
|
602343
|
+
}),
|
|
602344
|
+
"",
|
|
602345
|
+
`Chat: ${options2.chatTitle || options2.chatId} (${options2.chatType})`,
|
|
602346
|
+
`Session: ${options2.sessionKey}`,
|
|
602347
|
+
`Corpus query: ${clean4(corpus.query, 1e3)}`,
|
|
602348
|
+
`Corpus stats: ${JSON.stringify(corpus.stats)}`,
|
|
602349
|
+
`Selected seed: ${corpus.graphWalk.seed ? `${corpus.graphWalk.seed.node.text} degree=${corpus.graphWalk.seed.degree}` : "none"}`,
|
|
602350
|
+
corpus.fallbacks.length ? `Fallbacks: ${corpus.fallbacks.join("; ")}` : "Fallbacks: none",
|
|
602351
|
+
"",
|
|
602352
|
+
"Graph nodes:",
|
|
602353
|
+
walkNodes || "none",
|
|
602354
|
+
"",
|
|
602355
|
+
"Graph edges:",
|
|
602356
|
+
walkEdges || "none",
|
|
602357
|
+
"",
|
|
602358
|
+
"Source episodes:",
|
|
602359
|
+
episodes || "none"
|
|
602360
|
+
].join("\n");
|
|
602361
|
+
}
|
|
602362
|
+
function parseJsonObject(raw) {
|
|
602363
|
+
const text = raw.trim();
|
|
602364
|
+
if (!text) return null;
|
|
602365
|
+
const fenced = text.match(/```(?:json)?\s*([\s\S]*?)```/i)?.[1]?.trim();
|
|
602366
|
+
const candidate = fenced || text.slice(text.indexOf("{"), text.lastIndexOf("}") + 1);
|
|
602367
|
+
if (!candidate || !candidate.startsWith("{")) return null;
|
|
602368
|
+
try {
|
|
602369
|
+
const parsed = JSON.parse(candidate);
|
|
602370
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
602371
|
+
} catch {
|
|
602372
|
+
return null;
|
|
602373
|
+
}
|
|
602374
|
+
}
|
|
602375
|
+
function parseTelegramReflectionExtraction(raw) {
|
|
602376
|
+
const parsed = parseJsonObject(raw);
|
|
602377
|
+
if (!parsed) return null;
|
|
602378
|
+
const tags = Array.isArray(parsed.tags) ? parsed.tags.map((item) => {
|
|
602379
|
+
const obj = item;
|
|
602380
|
+
return {
|
|
602381
|
+
label: clean4(obj.label, 80),
|
|
602382
|
+
kind: clean4(obj.kind, 40) || "topic",
|
|
602383
|
+
confidence: clampConfidence(obj.confidence),
|
|
602384
|
+
sourceMessageIds: numberArray(obj.source_message_ids ?? obj.sourceMessageIds),
|
|
602385
|
+
targetEpisodeIds: stringArray(obj.target_episode_ids ?? obj.targetEpisodeIds),
|
|
602386
|
+
targetNodeIds: stringArray(obj.target_node_ids ?? obj.targetNodeIds)
|
|
602387
|
+
};
|
|
602388
|
+
}).filter((item) => item.label) : [];
|
|
602389
|
+
const summaries = Array.isArray(parsed.summaries) ? parsed.summaries.map((item) => {
|
|
602390
|
+
const obj = item;
|
|
602391
|
+
return {
|
|
602392
|
+
title: clean4(obj.title, 120),
|
|
602393
|
+
scope: clean4(obj.scope, 60) || "message_window",
|
|
602394
|
+
text: clean4(obj.text, 1200),
|
|
602395
|
+
confidence: clampConfidence(obj.confidence),
|
|
602396
|
+
sourceMessageIds: numberArray(obj.source_message_ids ?? obj.sourceMessageIds),
|
|
602397
|
+
targetEpisodeIds: stringArray(obj.target_episode_ids ?? obj.targetEpisodeIds)
|
|
602398
|
+
};
|
|
602399
|
+
}).filter((item) => item.title && item.text) : [];
|
|
602400
|
+
const titles = Array.isArray(parsed.titles) ? parsed.titles.map((item) => {
|
|
602401
|
+
const obj = item;
|
|
602402
|
+
return {
|
|
602403
|
+
title: clean4(obj.title, 120),
|
|
602404
|
+
target: clean4(obj.target, 60) || "artifact",
|
|
602405
|
+
confidence: clampConfidence(obj.confidence),
|
|
602406
|
+
sourceMessageIds: numberArray(obj.source_message_ids ?? obj.sourceMessageIds),
|
|
602407
|
+
targetEpisodeIds: stringArray(obj.target_episode_ids ?? obj.targetEpisodeIds)
|
|
602408
|
+
};
|
|
602409
|
+
}).filter((item) => item.title) : [];
|
|
602410
|
+
const extractions = Array.isArray(parsed.extractions) ? parsed.extractions.map((item) => {
|
|
602411
|
+
const obj = item;
|
|
602412
|
+
return {
|
|
602413
|
+
kind: clean4(obj.kind, 60) || "fact",
|
|
602414
|
+
text: clean4(obj.text, 1e3),
|
|
602415
|
+
confidence: clampConfidence(obj.confidence),
|
|
602416
|
+
sourceMessageIds: numberArray(obj.source_message_ids ?? obj.sourceMessageIds),
|
|
602417
|
+
targetEpisodeIds: stringArray(obj.target_episode_ids ?? obj.targetEpisodeIds),
|
|
602418
|
+
targetNodeIds: stringArray(obj.target_node_ids ?? obj.targetNodeIds)
|
|
602419
|
+
};
|
|
602420
|
+
}).filter((item) => item.text) : [];
|
|
602421
|
+
const links2 = Array.isArray(parsed.links) ? parsed.links.map((item) => {
|
|
602422
|
+
const obj = item;
|
|
602423
|
+
return {
|
|
602424
|
+
relation: clean4(obj.relation, 60) || "related_to",
|
|
602425
|
+
srcNodeText: clean4(obj.src_node_text ?? obj.srcNodeText, 180),
|
|
602426
|
+
dstNodeText: clean4(obj.dst_node_text ?? obj.dstNodeText, 180),
|
|
602427
|
+
confidence: clampConfidence(obj.confidence),
|
|
602428
|
+
fact: clean4(obj.fact, 500),
|
|
602429
|
+
sourceMessageIds: numberArray(obj.source_message_ids ?? obj.sourceMessageIds),
|
|
602430
|
+
targetEpisodeIds: stringArray(obj.target_episode_ids ?? obj.targetEpisodeIds)
|
|
602431
|
+
};
|
|
602432
|
+
}).filter((item) => item.srcNodeText && item.dstNodeText) : [];
|
|
602433
|
+
const followups = Array.isArray(parsed.followups) ? parsed.followups.map((item) => {
|
|
602434
|
+
const obj = item;
|
|
602435
|
+
const target = clean4(obj.target, 40);
|
|
602436
|
+
const replyTo = Number(obj.reply_to_message_id ?? obj.replyToMessageId);
|
|
602437
|
+
const normalizedTarget = target === "private_dm" ? "private_dm" : target === "same_group" ? "same_group" : "none";
|
|
602438
|
+
return {
|
|
602439
|
+
target: normalizedTarget,
|
|
602440
|
+
text: clean4(obj.text, 700),
|
|
602441
|
+
replyToMessageId: Number.isFinite(replyTo) ? Math.trunc(replyTo) : null,
|
|
602442
|
+
rationale: clean4(obj.rationale, 400),
|
|
602443
|
+
confidence: clampConfidence(obj.confidence)
|
|
602444
|
+
};
|
|
602445
|
+
}) : [];
|
|
602446
|
+
return {
|
|
602447
|
+
artifactTitle: clean4(parsed.artifact_title ?? parsed.artifactTitle, 140) || "Telegram reflection",
|
|
602448
|
+
tags,
|
|
602449
|
+
summaries,
|
|
602450
|
+
titles,
|
|
602451
|
+
extractions,
|
|
602452
|
+
links: links2,
|
|
602453
|
+
followups,
|
|
602454
|
+
raw
|
|
602455
|
+
};
|
|
602456
|
+
}
|
|
602457
|
+
async function runTelegramReflectionExtraction(options2) {
|
|
602458
|
+
const prompt = buildTelegramReflectionExtractionPrompt(options2);
|
|
602459
|
+
const result = await options2.backend.chatCompletion({
|
|
602460
|
+
messages: [
|
|
602461
|
+
{ role: "system", content: "You produce strict JSON for Telegram reflection memory extraction." },
|
|
602462
|
+
{ role: "user", content: prompt }
|
|
602463
|
+
],
|
|
602464
|
+
tools: [],
|
|
602465
|
+
temperature: 0.2,
|
|
602466
|
+
maxTokens: 1800,
|
|
602467
|
+
timeoutMs: options2.timeoutMs,
|
|
602468
|
+
think: false
|
|
602469
|
+
});
|
|
602470
|
+
return parseTelegramReflectionExtraction(result.choices[0]?.message?.content ?? "");
|
|
602471
|
+
}
|
|
602472
|
+
function memoryDbPaths(repoRoot) {
|
|
602473
|
+
return omniusMemoryDbPaths(repoRoot);
|
|
602474
|
+
}
|
|
602475
|
+
function allowedRelation(value2) {
|
|
602476
|
+
const relations = [
|
|
602477
|
+
"caused_by",
|
|
602478
|
+
"discovered_during",
|
|
602479
|
+
"fixed_by",
|
|
602480
|
+
"produced_by",
|
|
602481
|
+
"co_occurred_with",
|
|
602482
|
+
"requires",
|
|
602483
|
+
"is_instance_of",
|
|
602484
|
+
"related_to",
|
|
602485
|
+
"contains",
|
|
602486
|
+
"modified_by",
|
|
602487
|
+
"said_by",
|
|
602488
|
+
"appears_in",
|
|
602489
|
+
"alias_of",
|
|
602490
|
+
"authored_by",
|
|
602491
|
+
"uploaded_by",
|
|
602492
|
+
"replied_to",
|
|
602493
|
+
"depicts",
|
|
602494
|
+
"named_as",
|
|
602495
|
+
"face_match",
|
|
602496
|
+
"voice_sample_of",
|
|
602497
|
+
"speaker_candidate",
|
|
602498
|
+
"same_person_candidate"
|
|
602499
|
+
];
|
|
602500
|
+
return relations.includes(value2) ? value2 : "related_to";
|
|
602501
|
+
}
|
|
602502
|
+
function nodeText(prefix, value2) {
|
|
602503
|
+
return `${prefix}:${clean4(value2, 180).toLowerCase()}`;
|
|
602504
|
+
}
|
|
602505
|
+
function firstSourceEpisode(itemEpisodeIds, fallback) {
|
|
602506
|
+
return itemEpisodeIds[0] || fallback;
|
|
602507
|
+
}
|
|
602508
|
+
function commitTelegramReflectionExtraction(repoRoot, sessionKey, corpus, extraction) {
|
|
602509
|
+
const paths = memoryDbPaths(repoRoot);
|
|
602510
|
+
const graph = new TemporalGraph(paths.knowledge);
|
|
602511
|
+
const store2 = new EpisodeStore(paths.episodes, graph);
|
|
602512
|
+
try {
|
|
602513
|
+
const reflectionContent = [
|
|
602514
|
+
`Telegram reflection extraction: ${extraction.artifactTitle}`,
|
|
602515
|
+
`session: ${sessionKey}`,
|
|
602516
|
+
`seed: ${corpus.graphWalk.seed?.node.text || "none"}`,
|
|
602517
|
+
`tags: ${extraction.tags.map((tag) => tag.label).join(", ") || "none"}`,
|
|
602518
|
+
"",
|
|
602519
|
+
...extraction.summaries.map((summary) => `${summary.title}: ${summary.text}`),
|
|
602520
|
+
...extraction.extractions.map((item) => `${item.kind}: ${item.text}`)
|
|
602521
|
+
].join("\n");
|
|
602522
|
+
const reflectionEpisodeId = store2.insert({
|
|
602523
|
+
sessionId: sessionKey,
|
|
602524
|
+
modality: "reflection",
|
|
602525
|
+
toolName: "telegram_reflection_extraction",
|
|
602526
|
+
content: reflectionContent,
|
|
602527
|
+
metadata: {
|
|
602528
|
+
sourceSurface: "telegram_reflection",
|
|
602529
|
+
sessionKey,
|
|
602530
|
+
corpusStats: corpus.stats,
|
|
602531
|
+
selectedEpisodeIds: corpus.selectedEpisodeIds,
|
|
602532
|
+
extraction: {
|
|
602533
|
+
artifactTitle: extraction.artifactTitle,
|
|
602534
|
+
tags: extraction.tags,
|
|
602535
|
+
summaries: extraction.summaries,
|
|
602536
|
+
titles: extraction.titles,
|
|
602537
|
+
extractions: extraction.extractions,
|
|
602538
|
+
links: extraction.links,
|
|
602539
|
+
followups: extraction.followups
|
|
602540
|
+
}
|
|
602541
|
+
},
|
|
602542
|
+
importance: 8,
|
|
602543
|
+
decayClass: "procedural"
|
|
602544
|
+
});
|
|
602545
|
+
const artifactNode = graph.upsertNode({ text: nodeText("telegram_reflection", extraction.artifactTitle), nodeType: "concept" });
|
|
602546
|
+
let graphNodes = 1;
|
|
602547
|
+
let graphEdges = 0;
|
|
602548
|
+
const summaryEpisodeIds = [];
|
|
602549
|
+
const seedNodeId = corpus.graphWalk.seed?.node.id;
|
|
602550
|
+
if (seedNodeId) {
|
|
602551
|
+
graph.addEdge({
|
|
602552
|
+
srcId: artifactNode,
|
|
602553
|
+
dstId: seedNodeId,
|
|
602554
|
+
relation: "related_to",
|
|
602555
|
+
fact: `Reflection seed for ${extraction.artifactTitle}`,
|
|
602556
|
+
sourceEpisodeId: reflectionEpisodeId,
|
|
602557
|
+
modality: "reflection",
|
|
602558
|
+
confidence: 0.9
|
|
602559
|
+
});
|
|
602560
|
+
graphEdges++;
|
|
602561
|
+
}
|
|
602562
|
+
for (const tag of extraction.tags) {
|
|
602563
|
+
const tagNode = graph.upsertNode({ text: nodeText("tag", tag.label), nodeType: "concept" });
|
|
602564
|
+
graphNodes++;
|
|
602565
|
+
graph.addEdge({
|
|
602566
|
+
srcId: artifactNode,
|
|
602567
|
+
dstId: tagNode,
|
|
602568
|
+
relation: "contains",
|
|
602569
|
+
fact: `${tag.kind}: ${tag.label}`,
|
|
602570
|
+
sourceEpisodeId: firstSourceEpisode(tag.targetEpisodeIds, reflectionEpisodeId),
|
|
602571
|
+
modality: "reflection",
|
|
602572
|
+
confidence: tag.confidence
|
|
602573
|
+
});
|
|
602574
|
+
graphEdges++;
|
|
602575
|
+
}
|
|
602576
|
+
for (const summary of extraction.summaries) {
|
|
602577
|
+
const episodeId = store2.insert({
|
|
602578
|
+
sessionId: sessionKey,
|
|
602579
|
+
modality: "gist",
|
|
602580
|
+
toolName: "telegram_reflection_summary",
|
|
602581
|
+
content: `${summary.title}
|
|
602582
|
+
${summary.text}`,
|
|
602583
|
+
metadata: {
|
|
602584
|
+
sourceSurface: "telegram_reflection",
|
|
602585
|
+
sessionKey,
|
|
602586
|
+
scope: summary.scope,
|
|
602587
|
+
sourceMessageIds: summary.sourceMessageIds,
|
|
602588
|
+
targetEpisodeIds: summary.targetEpisodeIds
|
|
602589
|
+
},
|
|
602590
|
+
importance: Math.max(6, summary.confidence * 10),
|
|
602591
|
+
decayClass: "procedural",
|
|
602592
|
+
sourceEpisodeId: reflectionEpisodeId
|
|
602593
|
+
});
|
|
602594
|
+
summaryEpisodeIds.push(episodeId);
|
|
602595
|
+
const summaryNode = graph.upsertNode({ text: nodeText("summary", summary.title), nodeType: "concept" });
|
|
602596
|
+
graphNodes++;
|
|
602597
|
+
graph.addEdge({
|
|
602598
|
+
srcId: artifactNode,
|
|
602599
|
+
dstId: summaryNode,
|
|
602600
|
+
relation: "contains",
|
|
602601
|
+
fact: summary.text,
|
|
602602
|
+
sourceEpisodeId: episodeId,
|
|
602603
|
+
modality: "reflection",
|
|
602604
|
+
confidence: summary.confidence
|
|
602605
|
+
});
|
|
602606
|
+
graphEdges++;
|
|
602607
|
+
}
|
|
602608
|
+
for (const title of extraction.titles) {
|
|
602609
|
+
const titleNode = graph.upsertNode({ text: nodeText("title", title.title), nodeType: "concept" });
|
|
602610
|
+
graphNodes++;
|
|
602611
|
+
graph.addEdge({
|
|
602612
|
+
srcId: artifactNode,
|
|
602613
|
+
dstId: titleNode,
|
|
602614
|
+
relation: "contains",
|
|
602615
|
+
fact: `${title.target}: ${title.title}`,
|
|
602616
|
+
sourceEpisodeId: firstSourceEpisode(title.targetEpisodeIds, reflectionEpisodeId),
|
|
602617
|
+
modality: "reflection",
|
|
602618
|
+
confidence: title.confidence
|
|
602619
|
+
});
|
|
602620
|
+
graphEdges++;
|
|
602621
|
+
}
|
|
602622
|
+
for (const item of extraction.extractions) {
|
|
602623
|
+
const itemNode = graph.upsertNode({ text: nodeText(item.kind, item.text), nodeType: item.kind === "open_question" ? "event" : "concept" });
|
|
602624
|
+
graphNodes++;
|
|
602625
|
+
graph.addEdge({
|
|
602626
|
+
srcId: artifactNode,
|
|
602627
|
+
dstId: itemNode,
|
|
602628
|
+
relation: "contains",
|
|
602629
|
+
fact: item.text,
|
|
602630
|
+
sourceEpisodeId: firstSourceEpisode(item.targetEpisodeIds, reflectionEpisodeId),
|
|
602631
|
+
modality: "reflection",
|
|
602632
|
+
confidence: item.confidence
|
|
602633
|
+
});
|
|
602634
|
+
graphEdges++;
|
|
602635
|
+
}
|
|
602636
|
+
for (const link of extraction.links) {
|
|
602637
|
+
const src2 = graph.upsertNode({ text: clean4(link.srcNodeText, 180), nodeType: "concept" });
|
|
602638
|
+
const dst = graph.upsertNode({ text: clean4(link.dstNodeText, 180), nodeType: "concept" });
|
|
602639
|
+
graphNodes += 2;
|
|
602640
|
+
graph.addEdge({
|
|
602641
|
+
srcId: src2,
|
|
602642
|
+
dstId: dst,
|
|
602643
|
+
relation: allowedRelation(link.relation),
|
|
602644
|
+
fact: link.fact,
|
|
602645
|
+
sourceEpisodeId: firstSourceEpisode(link.targetEpisodeIds, reflectionEpisodeId),
|
|
602646
|
+
modality: "reflection",
|
|
602647
|
+
confidence: link.confidence
|
|
602648
|
+
});
|
|
602649
|
+
graphEdges++;
|
|
602650
|
+
}
|
|
602651
|
+
return { reflectionEpisodeId, summaryEpisodeIds, graphNodes, graphEdges };
|
|
602652
|
+
} finally {
|
|
602653
|
+
store2.close();
|
|
602654
|
+
graph.close();
|
|
602655
|
+
}
|
|
602656
|
+
}
|
|
602657
|
+
var init_telegram_reflection_extraction = __esm({
|
|
602658
|
+
"packages/cli/src/tui/telegram-reflection-extraction.ts"() {
|
|
602659
|
+
"use strict";
|
|
602660
|
+
init_dist7();
|
|
602661
|
+
init_memory_paths();
|
|
602662
|
+
}
|
|
602663
|
+
});
|
|
602664
|
+
|
|
601131
602665
|
// packages/cli/src/tui/vision-ingress.ts
|
|
601132
602666
|
var vision_ingress_exports = {};
|
|
601133
602667
|
__export(vision_ingress_exports, {
|
|
@@ -601283,9 +602817,9 @@ var init_vision_ingress = __esm({
|
|
|
601283
602817
|
|
|
601284
602818
|
// packages/cli/src/tui/telegram-bridge.ts
|
|
601285
602819
|
import { mkdirSync as mkdirSync63, existsSync as existsSync108, unlinkSync as unlinkSync21, readdirSync as readdirSync37, statSync as statSync36, statfsSync as statfsSync3, readFileSync as readFileSync88, writeFileSync as writeFileSync57 } from "node:fs";
|
|
601286
|
-
import { join as join123, resolve as resolve41, basename as
|
|
602820
|
+
import { join as join123, resolve as resolve41, basename as basename27, relative as relative13, isAbsolute as isAbsolute7, extname as extname16 } from "node:path";
|
|
601287
602821
|
import { writeFile as writeFileAsync } from "node:fs/promises";
|
|
601288
|
-
import { createHash as
|
|
602822
|
+
import { createHash as createHash23, randomInt } from "node:crypto";
|
|
601289
602823
|
function parseTelegramInteractionDecision(text, forcedRoute, options2 = {}) {
|
|
601290
602824
|
const cleaned = stripTelegramHiddenThinking(text).replace(/```(?:json)?/gi, "").replace(/```/g, "").trim();
|
|
601291
602825
|
const jsonText = cleaned.startsWith("{") ? cleaned : cleaned.match(/\{[\s\S]*\}/)?.[0] ?? "";
|
|
@@ -601321,6 +602855,29 @@ function parseTelegramInteractionDecision(text, forcedRoute, options2 = {}) {
|
|
|
601321
602855
|
return null;
|
|
601322
602856
|
}
|
|
601323
602857
|
}
|
|
602858
|
+
function parseTelegramReflectionFollowupDecision(text) {
|
|
602859
|
+
const cleaned = stripTelegramHiddenThinking(text).replace(/```(?:json)?/gi, "").replace(/```/g, "").trim();
|
|
602860
|
+
const jsonText = cleaned.startsWith("{") ? cleaned : cleaned.match(/\{[\s\S]*\}/)?.[0] ?? "";
|
|
602861
|
+
if (!jsonText) return null;
|
|
602862
|
+
try {
|
|
602863
|
+
const parsed = JSON.parse(jsonText);
|
|
602864
|
+
const shouldSendRaw = parsed["should_send"] ?? parsed["shouldSend"];
|
|
602865
|
+
const shouldSend = shouldSendRaw === true;
|
|
602866
|
+
const confidenceRaw = Number(parsed["confidence"]);
|
|
602867
|
+
const confidence2 = Number.isFinite(confidenceRaw) ? Math.max(0, Math.min(1, confidenceRaw)) : 0;
|
|
602868
|
+
const replyRaw = Number(parsed["reply_to_message_id"] ?? parsed["replyToMessageId"]);
|
|
602869
|
+
const replyToMessageId = Number.isFinite(replyRaw) && replyRaw > 0 ? Math.trunc(replyRaw) : void 0;
|
|
602870
|
+
return {
|
|
602871
|
+
shouldSend,
|
|
602872
|
+
text: String(parsed["text"] ?? "").trim().slice(0, 900),
|
|
602873
|
+
reason: String(parsed["reason"] ?? (shouldSend ? "model selected a scoped follow-up" : "model chose silence")).trim().slice(0, 240),
|
|
602874
|
+
confidence: confidence2,
|
|
602875
|
+
replyToMessageId
|
|
602876
|
+
};
|
|
602877
|
+
} catch {
|
|
602878
|
+
return null;
|
|
602879
|
+
}
|
|
602880
|
+
}
|
|
601324
602881
|
function convertMarkdownToTelegramHTML(md) {
|
|
601325
602882
|
let html = md;
|
|
601326
602883
|
html = html.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
@@ -601365,8 +602922,8 @@ function stripTelegramHiddenThinking(text) {
|
|
|
601365
602922
|
return withoutClosedThink.replace(/<think>[\s\S]*$/gi, "");
|
|
601366
602923
|
}
|
|
601367
602924
|
function sanitizeTelegramProgressText(text, maxLength) {
|
|
601368
|
-
const
|
|
601369
|
-
return
|
|
602925
|
+
const compact2 = stripTelegramHiddenThinking(text).replace(/\s+/g, " ").trim();
|
|
602926
|
+
return compact2.length > maxLength ? compact2.slice(0, Math.max(0, maxLength - 3)) + "..." : compact2;
|
|
601370
602927
|
}
|
|
601371
602928
|
function isCodebaseMemoryStatus(text) {
|
|
601372
602929
|
return /^\s*\[CODEBASE MEMORY\]/i.test(stripTelegramHiddenThinking(text));
|
|
@@ -601408,40 +602965,40 @@ function isTelegramNoReplySentinel(text) {
|
|
|
601408
602965
|
return lower === "no_reply" || lower.startsWith("no_reply");
|
|
601409
602966
|
}
|
|
601410
602967
|
function isTelegramInternalStatusText(text) {
|
|
601411
|
-
const
|
|
601412
|
-
if (!
|
|
601413
|
-
const lower =
|
|
601414
|
-
if (isTelegramNoReplySentinel(
|
|
602968
|
+
const compact2 = compactTelegramVisibleText(text);
|
|
602969
|
+
if (!compact2) return false;
|
|
602970
|
+
const lower = compact2.toLowerCase();
|
|
602971
|
+
if (isTelegramNoReplySentinel(compact2)) return true;
|
|
601415
602972
|
if (lower === "complete" || lower === "completed") return true;
|
|
601416
|
-
if (/^memory stage:/i.test(
|
|
601417
|
-
if (/^\[ppr[-_\s]?skip\]/i.test(
|
|
601418
|
-
if (/^(casual|ambient|group)\b.{0,180}\b(skipping|skipped|not directed|no action needed|no reply)\b/i.test(
|
|
601419
|
-
if (/^no further action needed\b/i.test(
|
|
601420
|
-
if (/^no action needed\b.{0,120}\b(task|complete|completed|done)\b/i.test(
|
|
601421
|
-
if (/^(there'?s|there is) no active task\b/i.test(
|
|
601422
|
-
if (/^everything'?s (done|complete|completed|wrapped up)\b/i.test(
|
|
601423
|
-
if (/\balready (been )?(provided|answered|handled|delivered) above\b/i.test(
|
|
601424
|
-
if (/\b(no remaining work|nothing left to do|task is complete|task has been completed)\b/i.test(
|
|
602973
|
+
if (/^memory stage:/i.test(compact2)) return true;
|
|
602974
|
+
if (/^\[ppr[-_\s]?skip\]/i.test(compact2)) return true;
|
|
602975
|
+
if (/^(casual|ambient|group)\b.{0,180}\b(skipping|skipped|not directed|no action needed|no reply)\b/i.test(compact2)) return true;
|
|
602976
|
+
if (/^no further action needed\b/i.test(compact2)) return true;
|
|
602977
|
+
if (/^no action needed\b.{0,120}\b(task|complete|completed|done)\b/i.test(compact2)) return true;
|
|
602978
|
+
if (/^(there'?s|there is) no active task\b/i.test(compact2)) return true;
|
|
602979
|
+
if (/^everything'?s (done|complete|completed|wrapped up)\b/i.test(compact2)) return true;
|
|
602980
|
+
if (/\balready (been )?(provided|answered|handled|delivered) above\b/i.test(compact2)) return true;
|
|
602981
|
+
if (/\b(no remaining work|nothing left to do|task is complete|task has been completed)\b/i.test(compact2)) return true;
|
|
601425
602982
|
return false;
|
|
601426
602983
|
}
|
|
601427
602984
|
function cleanTelegramVisibleReply(text, options2 = {}) {
|
|
601428
|
-
const
|
|
601429
|
-
if (!
|
|
601430
|
-
if (options2.suppressPotentialNoReplyPrefix && isTelegramPotentialNoReplyPrefix(
|
|
601431
|
-
if (isTelegramInternalStatusText(
|
|
601432
|
-
return dedupeTelegramVisibleReply(
|
|
602985
|
+
const clean5 = stripTelegramHiddenThinking(text).trim();
|
|
602986
|
+
if (!clean5) return "";
|
|
602987
|
+
if (options2.suppressPotentialNoReplyPrefix && isTelegramPotentialNoReplyPrefix(clean5)) return "";
|
|
602988
|
+
if (isTelegramInternalStatusText(clean5)) return "";
|
|
602989
|
+
return dedupeTelegramVisibleReply(clean5);
|
|
601433
602990
|
}
|
|
601434
602991
|
function dedupeTelegramVisibleReply(text) {
|
|
601435
602992
|
const paragraphs = text.split(/\n{2,}/);
|
|
601436
602993
|
const seenParagraphs = /* @__PURE__ */ new Set();
|
|
601437
602994
|
const collapsedParagraphs = [];
|
|
601438
602995
|
for (const paragraph of paragraphs) {
|
|
601439
|
-
const
|
|
601440
|
-
if (!
|
|
601441
|
-
const key = compactTelegramVisibleText(
|
|
602996
|
+
const clean5 = paragraph.trim();
|
|
602997
|
+
if (!clean5) continue;
|
|
602998
|
+
const key = compactTelegramVisibleText(clean5).toLowerCase();
|
|
601442
602999
|
if (seenParagraphs.has(key)) continue;
|
|
601443
603000
|
seenParagraphs.add(key);
|
|
601444
|
-
collapsedParagraphs.push(
|
|
603001
|
+
collapsedParagraphs.push(clean5);
|
|
601445
603002
|
}
|
|
601446
603003
|
const paragraphCollapsed = collapsedParagraphs.join("\n\n");
|
|
601447
603004
|
const sentenceLike = paragraphCollapsed.match(/[^.!?]+[.!?]+|[^.!?]+$/g);
|
|
@@ -601471,9 +603028,9 @@ function truncateTelegramContext(text, maxLength) {
|
|
|
601471
603028
|
[Telegram context truncated; use tools for full detail.]`;
|
|
601472
603029
|
}
|
|
601473
603030
|
function truncateTelegramContextLine(text, maxLength = TELEGRAM_CONTEXT_LINE_LIMIT) {
|
|
601474
|
-
const
|
|
601475
|
-
if (
|
|
601476
|
-
return `${
|
|
603031
|
+
const compact2 = stripTelegramHiddenThinking(text).replace(/\s+/g, " ").trim();
|
|
603032
|
+
if (compact2.length <= maxLength) return compact2;
|
|
603033
|
+
return `${compact2.slice(0, Math.max(0, maxLength - 3)).trimEnd()}...`;
|
|
601477
603034
|
}
|
|
601478
603035
|
function telegramSpeakerLabel(msg) {
|
|
601479
603036
|
if (msg.username && msg.username !== "unknown") return `@${msg.username}`;
|
|
@@ -601620,7 +603177,7 @@ function buildTelegramRuntimeContext(now = /* @__PURE__ */ new Date(), repoRoot)
|
|
|
601620
603177
|
].filter(Boolean).join("\n");
|
|
601621
603178
|
}
|
|
601622
603179
|
function telegramSessionIdFromKey(sessionKey) {
|
|
601623
|
-
return `telegram-${
|
|
603180
|
+
return `telegram-${createHash23("sha1").update(sessionKey).digest("hex").slice(0, 16)}`;
|
|
601624
603181
|
}
|
|
601625
603182
|
function selectTelegramFinalResponse(args) {
|
|
601626
603183
|
const committedVisibleReply = cleanTelegramVisibleReply(args.visibleReplyText || "");
|
|
@@ -601695,10 +603252,17 @@ function telegramSyntheticHelpSignatures() {
|
|
|
601695
603252
|
{ signature: "/help", description: "Show Telegram command help" },
|
|
601696
603253
|
{ signature: "/start", description: "Show Telegram bridge status and authentication instructions" },
|
|
601697
603254
|
{ signature: "/auth <code>", description: "Authenticate this Telegram user as bot admin using the TUI code" },
|
|
601698
|
-
{ signature: "/call", description: "Get the active voice call link when a call session is running" }
|
|
603255
|
+
{ signature: "/call", description: "Get the active voice call link when a call session is running" },
|
|
603256
|
+
{ signature: "/reflect", description: "Run scoped Telegram chat reflection over retained chat history" },
|
|
603257
|
+
{ signature: "/reflect status", description: "Show the latest scoped Telegram reflection artifact" },
|
|
603258
|
+
{ signature: "/reflect now", description: "Run reflection and let the model decide whether to post a public follow-up" },
|
|
603259
|
+
{ signature: "/reflect auto on|off", description: "Enable or disable model-gated idle follow-ups for this chat" },
|
|
603260
|
+
{ signature: "/reflection", description: "Alias for /reflect" },
|
|
603261
|
+
{ signature: "/daydream", description: "Alias for /reflect in Telegram chats" }
|
|
601699
603262
|
];
|
|
601700
603263
|
}
|
|
601701
603264
|
function telegramHelpCommandAllowed(cmd, scope) {
|
|
603265
|
+
if (cmd.name === "dream") return false;
|
|
601702
603266
|
if (scope === "admin") return cmd.implementationStatus === "implemented";
|
|
601703
603267
|
if (TELEGRAM_PUBLIC_HELP_COMMANDS.has(cmd.name)) return true;
|
|
601704
603268
|
return cmd.surfaces.agentTool && !cmd.safety.secretBearing && !cmd.safety.destructive && !cmd.safety.profileGated;
|
|
@@ -601729,6 +603293,65 @@ function buildTelegramHelpHTML(scope, maxPublicCommands = 24) {
|
|
|
601729
603293
|
}
|
|
601730
603294
|
return lines.join("\n");
|
|
601731
603295
|
}
|
|
603296
|
+
function formatTelegramReflectionSummaryHTML(artifact, opts = { autoFollowup: false }) {
|
|
603297
|
+
const topThreads = artifact.curiosityThreads.slice(0, 3);
|
|
603298
|
+
const topReplies = artifact.replyOpportunities.slice(0, 3);
|
|
603299
|
+
const groupPlans = artifact.outreachPlans.filter((plan) => plan.target === "same_group").slice(0, 2);
|
|
603300
|
+
const topTags = (artifact.tagging ?? []).slice(0, 6);
|
|
603301
|
+
const topSummaries = (artifact.summation ?? []).slice(0, 3);
|
|
603302
|
+
const topExtractions = (artifact.extraction ?? []).slice(0, 4);
|
|
603303
|
+
const topLinks = (artifact.linking ?? []).slice(0, 4);
|
|
603304
|
+
const lines = [
|
|
603305
|
+
`<b>Telegram reflection</b>`,
|
|
603306
|
+
`Scope: <code>${escapeTelegramHTML(artifact.chatTitle || artifact.chatId)}</code> (${escapeTelegramHTML(artifact.chatType)})`,
|
|
603307
|
+
`Window: ${artifact.messageWindow.totalRetained} retained messages`,
|
|
603308
|
+
artifact.corpus?.stats ? `Corpus: ${artifact.corpus.stats.selectedEpisodes} selected episodes, ${artifact.corpus.stats.graphNodesVisited} graph nodes, ${artifact.corpus.stats.graphEdgesTraversed} graph edges` : "",
|
|
603309
|
+
artifact.selectedSeed ? `Seed: <code>${escapeTelegramHTML(artifact.selectedSeed.nodeText)}</code>` : "",
|
|
603310
|
+
`Auto follow-up: <b>${opts.autoFollowup ? "on" : "off"}</b>`,
|
|
603311
|
+
opts.sentFollowup ? `Follow-up: <b>sent</b>` : opts.followupReason ? `Follow-up: ${escapeTelegramHTML(opts.followupReason)}` : "",
|
|
603312
|
+
"",
|
|
603313
|
+
topTags.length ? `<b>Tags</b>` : "",
|
|
603314
|
+
...topTags.map(
|
|
603315
|
+
(tag) => `- ${escapeTelegramHTML(tag.label)} (${escapeTelegramHTML(tag.kind)}, ${Math.round(tag.confidence * 100)}%)`
|
|
603316
|
+
),
|
|
603317
|
+
topSummaries.length ? "" : "",
|
|
603318
|
+
topSummaries.length ? `<b>Summaries</b>` : "",
|
|
603319
|
+
...topSummaries.map(
|
|
603320
|
+
(summary) => `- ${escapeTelegramHTML(summary.title)}: ${escapeTelegramHTML(summary.text)}`
|
|
603321
|
+
),
|
|
603322
|
+
topExtractions.length ? "" : "",
|
|
603323
|
+
topExtractions.length ? `<b>Extractions</b>` : "",
|
|
603324
|
+
...topExtractions.map(
|
|
603325
|
+
(item) => `- ${escapeTelegramHTML(item.kind)}: ${escapeTelegramHTML(item.text)}`
|
|
603326
|
+
),
|
|
603327
|
+
topLinks.length ? "" : "",
|
|
603328
|
+
topLinks.length ? `<b>Links</b>` : "",
|
|
603329
|
+
...topLinks.map(
|
|
603330
|
+
(link) => `- ${escapeTelegramHTML(link.srcNodeText)} -> ${escapeTelegramHTML(link.dstNodeText)} (${escapeTelegramHTML(link.relation)})`
|
|
603331
|
+
),
|
|
603332
|
+
artifact.corpus?.fallbacks?.length ? "" : "",
|
|
603333
|
+
artifact.corpus?.fallbacks?.length ? `<b>Fallbacks</b>` : "",
|
|
603334
|
+
...(artifact.corpus?.fallbacks ?? []).slice(0, 3).map((fallback) => `- ${escapeTelegramHTML(fallback)}`),
|
|
603335
|
+
"",
|
|
603336
|
+
topThreads.length ? `<b>Curiosity threads</b>` : "",
|
|
603337
|
+
...topThreads.map(
|
|
603338
|
+
(thread) => `- ${escapeTelegramHTML(thread.question)} (${Math.round(thread.intensity * 100)}%)`
|
|
603339
|
+
),
|
|
603340
|
+
topReplies.length ? "" : "",
|
|
603341
|
+
topReplies.length ? `<b>Reply opportunities</b>` : "",
|
|
603342
|
+
...topReplies.map(
|
|
603343
|
+
(item) => `- ${escapeTelegramHTML(item.trigger)} (${Math.round(item.confidence * 100)}%)`
|
|
603344
|
+
),
|
|
603345
|
+
groupPlans.length ? "" : "",
|
|
603346
|
+
groupPlans.length ? `<b>Same-group outreach plans</b>` : "",
|
|
603347
|
+
...groupPlans.map(
|
|
603348
|
+
(plan) => `- ${escapeTelegramHTML(plan.trigger)} (${Math.round(plan.confidence * 100)}%, ${escapeTelegramHTML(plan.gate)})`
|
|
603349
|
+
),
|
|
603350
|
+
"",
|
|
603351
|
+
"Saved as scoped Telegram context for future routing. It reflects chat history only, not the workspace filesystem."
|
|
603352
|
+
].filter((line) => line !== "");
|
|
603353
|
+
return lines.join("\n");
|
|
603354
|
+
}
|
|
601732
603355
|
function splitTelegramHTMLMessage(html, maxLength = 3600) {
|
|
601733
603356
|
const chunks = [];
|
|
601734
603357
|
let current = "";
|
|
@@ -602084,6 +603707,16 @@ function telegramImageMime(media) {
|
|
|
602084
603707
|
if (ext === ".tif" || ext === ".tiff") return "image/tiff";
|
|
602085
603708
|
return "image/jpeg";
|
|
602086
603709
|
}
|
|
603710
|
+
function appendMediaContextBlock(description, block) {
|
|
603711
|
+
const clean5 = block.trim();
|
|
603712
|
+
if (!clean5) return description;
|
|
603713
|
+
if (description.endsWith("]")) return `${description.slice(0, -1)}
|
|
603714
|
+
|
|
603715
|
+
${clean5}]`;
|
|
603716
|
+
return `${description}
|
|
603717
|
+
|
|
603718
|
+
${clean5}`;
|
|
603719
|
+
}
|
|
602087
603720
|
function telegramCachedMediaIsImage(entry) {
|
|
602088
603721
|
if (entry.mediaType === "photo") return true;
|
|
602089
603722
|
if (entry.mimeType?.toLowerCase().startsWith("image/")) return true;
|
|
@@ -602312,7 +603945,7 @@ function renderTelegramSubAgentError(username, error) {
|
|
|
602312
603945
|
process.stdout.write(` ${c3.dim("⎿")} ${c3.red("✘")} @${username}: ${c3.dim(preview)}
|
|
602313
603946
|
`);
|
|
602314
603947
|
}
|
|
602315
|
-
var TELEGRAM_SAFETY_PROMPT, ADMIN_DM_PROMPT, ADMIN_GROUP_PROMPT, TELEGRAM_PUBLIC_SOUL_PROFILE, TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT, TELEGRAM_PUBLIC_MEMORY_SCOPE_CONTRACT, GROUP_REPLY_DISCRETION_PROMPT, TELEGRAM_CHAT_MODE_PROMPT, ADMIN_CHAT_PROFILE_PROMPT, TELEGRAM_ACTION_RESPONSE_CONTRACT, TELEGRAM_CHAT_HISTORY_LIMIT, TELEGRAM_CONTEXT_RECENT_DEFAULT, TELEGRAM_CONTEXT_LINE_LIMIT, TELEGRAM_CONTEXT_SAMPLE_LIMIT, TELEGRAM_MEMORY_CARD_LIMIT, TELEGRAM_MEMORY_NOTE_LIMIT, TELEGRAM_MEMORY_STOPWORDS, TELEGRAM_PUBLIC_HELP_COMMANDS, TELEGRAM_REMINDER_SLASH_COMMANDS, TELEGRAM_IMAGE_EXTENSIONS, MEDIA_CACHE_TTL_MS, TELEGRAM_CHANNEL_DMN_SWEEP_MS, TELEGRAM_CHANNEL_DMN_IDLE_AFTER_MS, TELEGRAM_CHANNEL_DMN_MIN_INTERVAL_MS, TELEGRAM_CHANNEL_DMN_MIN_MESSAGES, TelegramBridge;
|
|
603948
|
+
var TELEGRAM_SAFETY_PROMPT, ADMIN_DM_PROMPT, ADMIN_GROUP_PROMPT, TELEGRAM_PUBLIC_SOUL_PROFILE, TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT, TELEGRAM_PUBLIC_MEMORY_SCOPE_CONTRACT, GROUP_REPLY_DISCRETION_PROMPT, TELEGRAM_CHAT_MODE_PROMPT, ADMIN_CHAT_PROFILE_PROMPT, TELEGRAM_ACTION_RESPONSE_CONTRACT, TELEGRAM_CHAT_HISTORY_LIMIT, TELEGRAM_CONTEXT_RECENT_DEFAULT, TELEGRAM_CONTEXT_LINE_LIMIT, TELEGRAM_CONTEXT_SAMPLE_LIMIT, TELEGRAM_MEMORY_CARD_LIMIT, TELEGRAM_MEMORY_NOTE_LIMIT, TELEGRAM_MEMORY_STOPWORDS, TELEGRAM_PUBLIC_HELP_COMMANDS, TELEGRAM_REMINDER_SLASH_COMMANDS, TELEGRAM_REFLECTION_SLASH_COMMANDS, TELEGRAM_IMAGE_EXTENSIONS, MEDIA_CACHE_TTL_MS, TELEGRAM_CHANNEL_DMN_SWEEP_MS, TELEGRAM_CHANNEL_DMN_IDLE_AFTER_MS, TELEGRAM_CHANNEL_DMN_MIN_INTERVAL_MS, TELEGRAM_CHANNEL_DMN_MIN_MESSAGES, TelegramBridge;
|
|
602316
603949
|
var init_telegram_bridge = __esm({
|
|
602317
603950
|
"packages/cli/src/tui/telegram-bridge.ts"() {
|
|
602318
603951
|
"use strict";
|
|
@@ -602328,7 +603961,10 @@ var init_telegram_bridge = __esm({
|
|
|
602328
603961
|
init_omnius_directory();
|
|
602329
603962
|
init_stimulation();
|
|
602330
603963
|
init_identity_memory_tool();
|
|
603964
|
+
init_visual_identity_association();
|
|
602331
603965
|
init_telegram_channel_dmn();
|
|
603966
|
+
init_telegram_reflection_corpus();
|
|
603967
|
+
init_telegram_reflection_extraction();
|
|
602332
603968
|
TELEGRAM_SAFETY_PROMPT = `
|
|
602333
603969
|
CRITICAL SAFETY NOTICE — PUBLIC TELEGRAM CHANNEL
|
|
602334
603970
|
|
|
@@ -602512,6 +604148,7 @@ Telegram response contract:
|
|
|
602512
604148
|
]);
|
|
602513
604149
|
TELEGRAM_PUBLIC_HELP_COMMANDS = /* @__PURE__ */ new Set(["help", "start", "auth", "call"]);
|
|
602514
604150
|
TELEGRAM_REMINDER_SLASH_COMMANDS = /* @__PURE__ */ new Set(["remind", "reminder", "reminders"]);
|
|
604151
|
+
TELEGRAM_REFLECTION_SLASH_COMMANDS = /* @__PURE__ */ new Set(["reflect", "reflection", "daydream", "dream"]);
|
|
602515
604152
|
TELEGRAM_IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp", ".tiff", ".tif", ".svg"]);
|
|
602516
604153
|
MEDIA_CACHE_TTL_MS = 30 * 60 * 1e3;
|
|
602517
604154
|
TELEGRAM_CHANNEL_DMN_SWEEP_MS = 2 * 60 * 1e3;
|
|
@@ -602614,6 +604251,8 @@ Telegram response contract:
|
|
|
602614
604251
|
channelDmnRunning = /* @__PURE__ */ new Set();
|
|
602615
604252
|
/** Daydream artifact already used to force a live-router check. */
|
|
602616
604253
|
channelDmnPromptedArtifactAt = /* @__PURE__ */ new Map();
|
|
604254
|
+
/** Per-chat reflection settings for model-gated idle follow-ups. */
|
|
604255
|
+
channelReflectionState = /* @__PURE__ */ new Map();
|
|
602617
604256
|
/** Set admin user ID filter */
|
|
602618
604257
|
setAdmin(userId) {
|
|
602619
604258
|
this.adminUserId = userId;
|
|
@@ -602698,7 +604337,7 @@ Telegram response contract:
|
|
|
602698
604337
|
return !!this.adminAuthChallenge && this.adminAuthChallenge.expiresAtMs > Date.now();
|
|
602699
604338
|
}
|
|
602700
604339
|
hashAdminAuthCode(code8) {
|
|
602701
|
-
return
|
|
604340
|
+
return createHash23("sha256").update(`omnius-telegram-admin:${code8.trim()}`).digest("hex");
|
|
602702
604341
|
}
|
|
602703
604342
|
viewIdForMessage(msg) {
|
|
602704
604343
|
return `telegram-${this.sessionKeyForMessage(msg).replace(/[^A-Za-z0-9_-]/g, "-")}`;
|
|
@@ -602769,6 +604408,69 @@ Telegram response contract:
|
|
|
602769
604408
|
result.success ? result.output || "Reminder updated." : result.error || `/${cmd} failed`
|
|
602770
604409
|
);
|
|
602771
604410
|
}
|
|
604411
|
+
async handleTelegramReflectionSlash(msg, commandText) {
|
|
604412
|
+
if (!this.repoRoot) {
|
|
604413
|
+
await this.replyToTelegramMessage(msg, "Telegram reflection storage is not available yet.");
|
|
604414
|
+
return;
|
|
604415
|
+
}
|
|
604416
|
+
const sessionKey = this.sessionKeyForMessage(msg);
|
|
604417
|
+
this.ensureTelegramConversationLoaded(sessionKey);
|
|
604418
|
+
const first2 = commandText.trim().split(/\s+/)[0] ?? "";
|
|
604419
|
+
const commandName = first2.slice(1).split("@")[0]?.toLowerCase() || "reflect";
|
|
604420
|
+
const arg = commandText.trim().slice(first2.length).trim();
|
|
604421
|
+
const lower = arg.toLowerCase();
|
|
604422
|
+
const state = this.reflectionStateForSession(sessionKey);
|
|
604423
|
+
if (commandName === "dream" && (lower === "deep" || lower === "lucid" || lower === "consolidate")) {
|
|
604424
|
+
await this.replyToTelegramMessage(
|
|
604425
|
+
msg,
|
|
604426
|
+
"Telegram /dream is scoped to chat reflection and does not start filesystem dream mode. Use /reflect, /reflect now, or run /dream in the TUI terminal."
|
|
604427
|
+
);
|
|
604428
|
+
return;
|
|
604429
|
+
}
|
|
604430
|
+
if (lower === "auto on" || lower === "on") {
|
|
604431
|
+
state.autoFollowup = true;
|
|
604432
|
+
this.saveTelegramConversationState(sessionKey);
|
|
604433
|
+
await this.replyToTelegramMessage(msg, "Scoped Telegram reflection auto follow-up is on for this chat. Idle cycles remain model-gated and public-only.");
|
|
604434
|
+
return;
|
|
604435
|
+
}
|
|
604436
|
+
if (lower === "auto off" || lower === "off" || lower === "stop") {
|
|
604437
|
+
state.autoFollowup = false;
|
|
604438
|
+
this.saveTelegramConversationState(sessionKey);
|
|
604439
|
+
await this.replyToTelegramMessage(msg, "Scoped Telegram reflection auto follow-up is off for this chat.");
|
|
604440
|
+
return;
|
|
604441
|
+
}
|
|
604442
|
+
if (lower === "auto" || lower === "status" || lower === "show") {
|
|
604443
|
+
const latest = this.latestTelegramChannelDaydream(sessionKey);
|
|
604444
|
+
const html2 = latest ? formatTelegramReflectionSummaryHTML(latest, { autoFollowup: state.autoFollowup }) : `<b>Telegram reflection</b>
|
|
604445
|
+
No scoped reflection artifact exists yet for this chat. Use <code>/reflect</code> to build one from retained Telegram history.`;
|
|
604446
|
+
await this.replyToTelegramMessage(msg, html2, {
|
|
604447
|
+
html: true,
|
|
604448
|
+
replyToMessageId: msg.chatType !== "private" ? msg.messageId : void 0
|
|
604449
|
+
});
|
|
604450
|
+
return;
|
|
604451
|
+
}
|
|
604452
|
+
const artifact = await this.runTelegramChannelDmnForSession(sessionKey, "telegram-command", Date.now(), true);
|
|
604453
|
+
if (!artifact) {
|
|
604454
|
+
await this.replyToTelegramMessage(
|
|
604455
|
+
msg,
|
|
604456
|
+
"No retained Telegram chat history is available for scoped reflection yet. Send a few messages in this chat first, then run /reflect again."
|
|
604457
|
+
);
|
|
604458
|
+
return;
|
|
604459
|
+
}
|
|
604460
|
+
let followup;
|
|
604461
|
+
if (lower === "now" || lower === "reply" || lower === "send") {
|
|
604462
|
+
followup = await this.maybeSendTelegramReflectionFollowup(sessionKey, artifact, "telegram-command");
|
|
604463
|
+
}
|
|
604464
|
+
const html = formatTelegramReflectionSummaryHTML(artifact, {
|
|
604465
|
+
autoFollowup: state.autoFollowup,
|
|
604466
|
+
sentFollowup: followup?.sent,
|
|
604467
|
+
followupReason: followup?.reason
|
|
604468
|
+
});
|
|
604469
|
+
await this.replyToTelegramMessage(msg, html, {
|
|
604470
|
+
html: true,
|
|
604471
|
+
replyToMessageId: msg.chatType !== "private" ? msg.messageId : void 0
|
|
604472
|
+
});
|
|
604473
|
+
}
|
|
602772
604474
|
/** Write to the scrollable TUI waterfall area (respects status bar scroll region) */
|
|
602773
604475
|
tuiWrite(fn) {
|
|
602774
604476
|
if (this.writeContent) {
|
|
@@ -602887,9 +604589,9 @@ Telegram response contract:
|
|
|
602887
604589
|
return reply;
|
|
602888
604590
|
}
|
|
602889
604591
|
quoteTelegramContextBlock(text, maxLength = 1800) {
|
|
602890
|
-
const
|
|
602891
|
-
const clipped =
|
|
602892
|
-
[reply context truncated]` :
|
|
604592
|
+
const clean5 = stripTelegramHiddenThinking(text).trim();
|
|
604593
|
+
const clipped = clean5.length > maxLength ? `${clean5.slice(0, Math.max(0, maxLength - 60)).trimEnd()}
|
|
604594
|
+
[reply context truncated]` : clean5;
|
|
602893
604595
|
return clipped.split(/\r?\n/).map((line) => `> ${line}`).join("\n");
|
|
602894
604596
|
}
|
|
602895
604597
|
buildTelegramCurrentReplyContext(sessionKey, msg) {
|
|
@@ -602995,6 +604697,7 @@ ${mediaContext}` : ""
|
|
|
602995
604697
|
const modality = media.type === "audio" || media.type === "voice" ? "audio" : telegramMediaIsImage(media) ? "visual" : "text";
|
|
602996
604698
|
const payload = {
|
|
602997
604699
|
sourceSurface: "telegram",
|
|
604700
|
+
sessionId: this.sessionKeyForMessage(msg),
|
|
602998
604701
|
scope: this.telegramMemoryScope(msg),
|
|
602999
604702
|
sender,
|
|
603000
604703
|
message: {
|
|
@@ -603036,7 +604739,7 @@ ${mediaContext}` : ""
|
|
|
603036
604739
|
return payload;
|
|
603037
604740
|
}
|
|
603038
604741
|
telegramConversationPath(sessionKey) {
|
|
603039
|
-
const safe =
|
|
604742
|
+
const safe = createHash23("sha1").update(sessionKey).digest("hex").slice(0, 20);
|
|
603040
604743
|
return join123(this.telegramConversationDir, `${safe}.json`);
|
|
603041
604744
|
}
|
|
603042
604745
|
telegramPersonalityScope(sessionKey, msg) {
|
|
@@ -603076,6 +604779,13 @@ ${mediaContext}` : ""
|
|
|
603076
604779
|
if (parsed.stimulation) {
|
|
603077
604780
|
this.stimulation.setState(sessionKey, parsed.stimulation);
|
|
603078
604781
|
}
|
|
604782
|
+
if (parsed.reflection) {
|
|
604783
|
+
this.channelReflectionState.set(sessionKey, {
|
|
604784
|
+
autoFollowup: parsed.reflection.autoFollowup === true,
|
|
604785
|
+
lastFollowupAt: typeof parsed.reflection.lastFollowupAt === "number" ? parsed.reflection.lastFollowupAt : void 0,
|
|
604786
|
+
lastFollowupArtifactAt: typeof parsed.reflection.lastFollowupArtifactAt === "string" ? parsed.reflection.lastFollowupArtifactAt : void 0
|
|
604787
|
+
});
|
|
604788
|
+
}
|
|
603079
604789
|
} catch {
|
|
603080
604790
|
}
|
|
603081
604791
|
}
|
|
@@ -603110,7 +604820,8 @@ ${mediaContext}` : ""
|
|
|
603110
604820
|
history: this.chatHistory.get(sessionKey) ?? [],
|
|
603111
604821
|
participants,
|
|
603112
604822
|
memoryCards: this.chatMemoryCards.get(sessionKey) ?? [],
|
|
603113
|
-
stimulation: this.stimulation.getState(sessionKey)
|
|
604823
|
+
stimulation: this.stimulation.getState(sessionKey),
|
|
604824
|
+
reflection: this.channelReflectionState.get(sessionKey) ?? { autoFollowup: false }
|
|
603114
604825
|
};
|
|
603115
604826
|
writeFileSync57(this.telegramConversationPath(sessionKey), JSON.stringify(payload, null, 2) + "\n", "utf8");
|
|
603116
604827
|
} catch {
|
|
@@ -603120,6 +604831,21 @@ ${mediaContext}` : ""
|
|
|
603120
604831
|
if (!this.repoRoot) return null;
|
|
603121
604832
|
return latestTelegramChannelDaydream(this.repoRoot, sessionKey);
|
|
603122
604833
|
}
|
|
604834
|
+
reflectionStateForSession(sessionKey) {
|
|
604835
|
+
const existing = this.channelReflectionState.get(sessionKey);
|
|
604836
|
+
if (existing) return existing;
|
|
604837
|
+
const created = { autoFollowup: false };
|
|
604838
|
+
this.channelReflectionState.set(sessionKey, created);
|
|
604839
|
+
return created;
|
|
604840
|
+
}
|
|
604841
|
+
telegramReflectionEmbeddingConfig() {
|
|
604842
|
+
if (!this.agentConfig || this.agentConfig.backendType !== "ollama") return false;
|
|
604843
|
+
return {
|
|
604844
|
+
baseUrl: this.agentConfig.backendUrl,
|
|
604845
|
+
model: process.env["OMNIUS_EMBEDDING_MODEL"] || "nomic-embed-text",
|
|
604846
|
+
timeoutMs: Math.min(Math.max(this.agentConfig.timeoutMs ?? 3e4, 5e3), 3e4)
|
|
604847
|
+
};
|
|
604848
|
+
}
|
|
603123
604849
|
buildTelegramChannelDaydreamInput(sessionKey, nowMs = Date.now()) {
|
|
603124
604850
|
const history = this.chatHistory.get(sessionKey) ?? [];
|
|
603125
604851
|
if (history.length === 0) return null;
|
|
@@ -603153,11 +604879,18 @@ ${mediaContext}` : ""
|
|
|
603153
604879
|
role: entry.role,
|
|
603154
604880
|
speaker: entry.speaker,
|
|
603155
604881
|
username: entry.username,
|
|
604882
|
+
firstName: entry.firstName,
|
|
604883
|
+
fromUserId: entry.fromUserId,
|
|
603156
604884
|
text: entry.text,
|
|
603157
604885
|
ts: entry.ts,
|
|
603158
604886
|
mode: entry.mode,
|
|
604887
|
+
chatId: entry.chatId,
|
|
604888
|
+
chatType: entry.chatType,
|
|
604889
|
+
chatTitle: entry.chatTitle,
|
|
603159
604890
|
messageId: entry.messageId,
|
|
604891
|
+
messageThreadId: entry.messageThreadId,
|
|
603160
604892
|
replyToMessageId: entry.replyToMessageId,
|
|
604893
|
+
replyContext: entry.replyContext,
|
|
603161
604894
|
mediaSummary: entry.mediaSummary
|
|
603162
604895
|
})),
|
|
603163
604896
|
participants,
|
|
@@ -603172,7 +604905,7 @@ ${mediaContext}` : ""
|
|
|
603172
604905
|
if (this.subAgents.has(sessionKey)) return null;
|
|
603173
604906
|
const input = this.buildTelegramChannelDaydreamInput(sessionKey, nowMs);
|
|
603174
604907
|
if (!input) return null;
|
|
603175
|
-
if (input.chatType === "private") return null;
|
|
604908
|
+
if (input.chatType === "private" && !force) return null;
|
|
603176
604909
|
const lastMessageAt = input.history.map((entry) => entry.ts).filter((ts) => typeof ts === "number").sort((a2, b) => b - a2)[0] ?? nowMs;
|
|
603177
604910
|
const lastRunAt = this.channelDmnLastRunAt.get(sessionKey) ?? 0;
|
|
603178
604911
|
if (!force) {
|
|
@@ -603182,9 +604915,51 @@ ${mediaContext}` : ""
|
|
|
603182
604915
|
}
|
|
603183
604916
|
this.channelDmnRunning.add(sessionKey);
|
|
603184
604917
|
try {
|
|
603185
|
-
const
|
|
604918
|
+
const corpus = await buildTelegramReflectionCorpus({
|
|
604919
|
+
repoRoot: this.repoRoot,
|
|
604920
|
+
sessionKey,
|
|
604921
|
+
chatId: input.chatId,
|
|
604922
|
+
chatType: input.chatType,
|
|
604923
|
+
chatTitle: input.chatTitle,
|
|
604924
|
+
generatedAtMs: nowMs,
|
|
604925
|
+
history: input.history,
|
|
604926
|
+
embeddingConfig: this.telegramReflectionEmbeddingConfig()
|
|
604927
|
+
});
|
|
604928
|
+
let extraction = null;
|
|
604929
|
+
let extractionCommit;
|
|
604930
|
+
if (this.agentConfig) {
|
|
604931
|
+
try {
|
|
604932
|
+
const backend = new OllamaAgenticBackend(
|
|
604933
|
+
this.agentConfig.backendUrl,
|
|
604934
|
+
this.agentConfig.model,
|
|
604935
|
+
this.agentConfig.apiKey
|
|
604936
|
+
);
|
|
604937
|
+
extraction = await runTelegramReflectionExtraction({
|
|
604938
|
+
backend: {
|
|
604939
|
+
chatCompletion: (args) => backend.chatCompletion(args)
|
|
604940
|
+
},
|
|
604941
|
+
corpus,
|
|
604942
|
+
sessionKey,
|
|
604943
|
+
chatId: input.chatId,
|
|
604944
|
+
chatType: input.chatType,
|
|
604945
|
+
chatTitle: input.chatTitle,
|
|
604946
|
+
timeoutMs: Math.min(Math.max(this.agentConfig.timeoutMs ?? 3e4, 5e3), 3e4)
|
|
604947
|
+
});
|
|
604948
|
+
if (extraction) {
|
|
604949
|
+
extractionCommit = commitTelegramReflectionExtraction(this.repoRoot, sessionKey, corpus, extraction);
|
|
604950
|
+
} else {
|
|
604951
|
+
corpus.fallbacks.push("structured extraction unavailable: model returned no valid JSON");
|
|
604952
|
+
}
|
|
604953
|
+
} catch (err) {
|
|
604954
|
+
corpus.fallbacks.push(`structured extraction unavailable: ${err instanceof Error ? err.message : String(err)}`);
|
|
604955
|
+
}
|
|
604956
|
+
} else {
|
|
604957
|
+
corpus.fallbacks.push("structured extraction unavailable: backend unavailable");
|
|
604958
|
+
}
|
|
604959
|
+
const artifact = buildTelegramChannelDaydream(input, corpus, extraction, extractionCommit);
|
|
603186
604960
|
writeTelegramChannelDaydream(this.repoRoot, artifact);
|
|
603187
604961
|
this.channelDmnLastRunAt.set(sessionKey, nowMs);
|
|
604962
|
+
this.channelDmnPromptedArtifactAt.delete(sessionKey);
|
|
603188
604963
|
void reason;
|
|
603189
604964
|
return artifact;
|
|
603190
604965
|
} finally {
|
|
@@ -603196,7 +604971,123 @@ ${mediaContext}` : ""
|
|
|
603196
604971
|
this.ensureAllTelegramConversationsLoaded();
|
|
603197
604972
|
const now = Date.now();
|
|
603198
604973
|
for (const sessionKey of this.chatHistory.keys()) {
|
|
603199
|
-
await this.runTelegramChannelDmnForSession(sessionKey, reason, now).catch(() => null);
|
|
604974
|
+
const artifact = await this.runTelegramChannelDmnForSession(sessionKey, reason, now).catch(() => null);
|
|
604975
|
+
if (!artifact) continue;
|
|
604976
|
+
const reflection = this.reflectionStateForSession(sessionKey);
|
|
604977
|
+
if (reflection.autoFollowup) {
|
|
604978
|
+
await this.maybeSendTelegramReflectionFollowup(sessionKey, artifact, reason).catch(() => null);
|
|
604979
|
+
}
|
|
604980
|
+
}
|
|
604981
|
+
}
|
|
604982
|
+
telegramChatIdFromArtifact(artifact) {
|
|
604983
|
+
const numeric = Number(artifact.chatId);
|
|
604984
|
+
return Number.isFinite(numeric) && String(Math.trunc(numeric)) === artifact.chatId ? Math.trunc(numeric) : artifact.chatId;
|
|
604985
|
+
}
|
|
604986
|
+
async maybeSendTelegramReflectionFollowup(sessionKey, artifact, reason = "reflection") {
|
|
604987
|
+
if (!this.agentConfig) return { sent: false, reason: "backend unavailable" };
|
|
604988
|
+
if (artifact.chatType === "private") return { sent: false, reason: "private chat reflection stored without autonomous outreach" };
|
|
604989
|
+
const state = this.reflectionStateForSession(sessionKey);
|
|
604990
|
+
if (state.lastFollowupArtifactAt === artifact.generatedAt) {
|
|
604991
|
+
return { sent: false, reason: "follow-up already evaluated for this artifact" };
|
|
604992
|
+
}
|
|
604993
|
+
const now = Date.now();
|
|
604994
|
+
if (state.lastFollowupAt && now - state.lastFollowupAt < 60 * 6e4) {
|
|
604995
|
+
return { sent: false, reason: "rate limit held public follow-up" };
|
|
604996
|
+
}
|
|
604997
|
+
const candidateMessageIds = Array.from(new Set([
|
|
604998
|
+
...artifact.curiosityThreads.flatMap((thread) => thread.sourceMessages ?? []),
|
|
604999
|
+
...artifact.memoryProposals.flatMap((proposal) => proposal.sourceMessages ?? []),
|
|
605000
|
+
...(artifact.tagging ?? []).flatMap((item) => item.sourceMessageIds ?? []),
|
|
605001
|
+
...(artifact.summation ?? []).flatMap((item) => item.sourceMessageIds ?? []),
|
|
605002
|
+
...(artifact.titling ?? []).flatMap((item) => item.sourceMessageIds ?? []),
|
|
605003
|
+
...(artifact.extraction ?? []).flatMap((item) => item.sourceMessageIds ?? []),
|
|
605004
|
+
...(artifact.linking ?? []).flatMap((item) => item.sourceMessageIds ?? []),
|
|
605005
|
+
...(artifact.extractionFollowups ?? []).map((item) => item.replyToMessageId).filter((id) => typeof id === "number")
|
|
605006
|
+
].filter((id) => typeof id === "number" && Number.isFinite(id))));
|
|
605007
|
+
const context2 = this.buildTelegramConversationContextStream(sessionKey, {
|
|
605008
|
+
chatId: this.telegramChatIdFromArtifact(artifact),
|
|
605009
|
+
chatType: artifact.chatType,
|
|
605010
|
+
chatTitle: artifact.chatTitle,
|
|
605011
|
+
text: `[internal Telegram reflection cycle: ${reason}]`,
|
|
605012
|
+
username: this.state.botUsername || "omnius",
|
|
605013
|
+
firstName: "Omnius",
|
|
605014
|
+
fromUserId: 0,
|
|
605015
|
+
messageId: 0
|
|
605016
|
+
}, 40);
|
|
605017
|
+
const prompt = [
|
|
605018
|
+
"You are deciding whether an idle Telegram reflection cycle should post one public follow-up in the same group.",
|
|
605019
|
+
'Return JSON only: {"should_send":boolean,"text":"public message text","reply_to_message_id":number|null,"confidence":0.0-1.0,"reason":"short reason"}.',
|
|
605020
|
+
"",
|
|
605021
|
+
"Hard constraints:",
|
|
605022
|
+
"- Use only the Telegram chat context and reflection artifact below.",
|
|
605023
|
+
"- Do not inspect or reference the workspace filesystem.",
|
|
605024
|
+
"- Default should_send=false unless a concise public follow-up is timely, low-intrusion, and clearly useful.",
|
|
605025
|
+
"- Do not reveal hidden meta-analysis, local paths, internal tools, or that a private artifact exists.",
|
|
605026
|
+
"- If sending, write one short message under 700 characters.",
|
|
605027
|
+
"- Prefer replying to one of the candidate message IDs when the follow-up is anchored to old content.",
|
|
605028
|
+
"- Private DM outreach is admin-review only and must not be sent by this autonomous public follow-up path.",
|
|
605029
|
+
"",
|
|
605030
|
+
`Candidate reply message IDs: ${candidateMessageIds.length ? candidateMessageIds.join(", ") : "none"}`,
|
|
605031
|
+
"",
|
|
605032
|
+
formatTelegramChannelDaydreamContext(artifact),
|
|
605033
|
+
"",
|
|
605034
|
+
context2
|
|
605035
|
+
].join("\n");
|
|
605036
|
+
try {
|
|
605037
|
+
const backend = new OllamaAgenticBackend(
|
|
605038
|
+
this.agentConfig.backendUrl,
|
|
605039
|
+
this.agentConfig.model,
|
|
605040
|
+
this.agentConfig.apiKey
|
|
605041
|
+
);
|
|
605042
|
+
const result = await backend.chatCompletion({
|
|
605043
|
+
messages: [
|
|
605044
|
+
{ role: "system", content: "You are a Telegram public-follow-up discretion model. Output strict JSON only." },
|
|
605045
|
+
{ role: "user", content: prompt }
|
|
605046
|
+
],
|
|
605047
|
+
tools: [],
|
|
605048
|
+
temperature: 0.2,
|
|
605049
|
+
maxTokens: 300,
|
|
605050
|
+
timeoutMs: Math.min(Math.max(this.agentConfig.timeoutMs ?? 3e4, 5e3), 2e4),
|
|
605051
|
+
think: false
|
|
605052
|
+
});
|
|
605053
|
+
const decision = parseTelegramReflectionFollowupDecision(result.choices[0]?.message?.content ?? "");
|
|
605054
|
+
state.lastFollowupArtifactAt = artifact.generatedAt;
|
|
605055
|
+
if (!decision) {
|
|
605056
|
+
this.saveTelegramConversationState(sessionKey);
|
|
605057
|
+
return { sent: false, reason: "model returned no usable follow-up decision" };
|
|
605058
|
+
}
|
|
605059
|
+
if (!decision.shouldSend || !decision.text || decision.confidence < 0.66) {
|
|
605060
|
+
this.saveTelegramConversationState(sessionKey);
|
|
605061
|
+
return { sent: false, reason: decision.reason || "model chose silence" };
|
|
605062
|
+
}
|
|
605063
|
+
const replyTo = decision.replyToMessageId && candidateMessageIds.includes(decision.replyToMessageId) ? decision.replyToMessageId : void 0;
|
|
605064
|
+
const chatId = this.telegramChatIdFromArtifact(artifact);
|
|
605065
|
+
const sentMessageId = await this.sendMessageHTML(
|
|
605066
|
+
chatId,
|
|
605067
|
+
convertMarkdownToTelegramHTML(decision.text),
|
|
605068
|
+
replyTo
|
|
605069
|
+
);
|
|
605070
|
+
this.recordTelegramAssistantMessage({
|
|
605071
|
+
chatId,
|
|
605072
|
+
chatType: artifact.chatType,
|
|
605073
|
+
chatTitle: artifact.chatTitle,
|
|
605074
|
+
text: decision.text,
|
|
605075
|
+
username: this.state.botUsername || "omnius",
|
|
605076
|
+
firstName: "Omnius",
|
|
605077
|
+
fromUserId: 0,
|
|
605078
|
+
messageId: sentMessageId ?? 0
|
|
605079
|
+
}, decision.text, "chat", {
|
|
605080
|
+
messageId: sentMessageId,
|
|
605081
|
+
replyToMessageId: replyTo
|
|
605082
|
+
});
|
|
605083
|
+
state.lastFollowupAt = now;
|
|
605084
|
+
this.saveTelegramConversationState(sessionKey);
|
|
605085
|
+
this.tuiWrite(() => renderTelegramSubAgentEvent("reflection", `sent scoped Telegram follow-up (${decision.confidence.toFixed(2)}): ${decision.reason}`));
|
|
605086
|
+
return { sent: true, reason: decision.reason };
|
|
605087
|
+
} catch (err) {
|
|
605088
|
+
state.lastFollowupArtifactAt = artifact.generatedAt;
|
|
605089
|
+
this.saveTelegramConversationState(sessionKey);
|
|
605090
|
+
return { sent: false, reason: err instanceof Error ? err.message : String(err) };
|
|
603200
605091
|
}
|
|
603201
605092
|
}
|
|
603202
605093
|
formatLatestTelegramChannelDaydreamContext(sessionKey) {
|
|
@@ -603220,6 +605111,22 @@ ${mediaContext}` : ""
|
|
|
603220
605111
|
return "";
|
|
603221
605112
|
}
|
|
603222
605113
|
}
|
|
605114
|
+
upsertTelegramReflectionHistoryEntry(sessionKey, entry) {
|
|
605115
|
+
if (!this.repoRoot || entry.chatId === void 0) return;
|
|
605116
|
+
try {
|
|
605117
|
+
upsertTelegramReflectionMessage(
|
|
605118
|
+
this.repoRoot,
|
|
605119
|
+
sessionKey,
|
|
605120
|
+
entry,
|
|
605121
|
+
{
|
|
605122
|
+
chatId: String(entry.chatId),
|
|
605123
|
+
chatType: entry.chatType || "unknown",
|
|
605124
|
+
chatTitle: entry.chatTitle
|
|
605125
|
+
}
|
|
605126
|
+
);
|
|
605127
|
+
} catch {
|
|
605128
|
+
}
|
|
605129
|
+
}
|
|
603223
605130
|
recordTelegramUserMessage(msg, mode, textOverride) {
|
|
603224
605131
|
const sessionKey = this.sessionKeyForMessage(msg);
|
|
603225
605132
|
const mediaSummary = summarizeTelegramMessageAttachments(msg);
|
|
@@ -603242,6 +605149,7 @@ ${mediaContext}` : ""
|
|
|
603242
605149
|
mediaSummary
|
|
603243
605150
|
};
|
|
603244
605151
|
this.recordChatHistory(sessionKey, entry);
|
|
605152
|
+
this.upsertTelegramReflectionHistoryEntry(sessionKey, entry);
|
|
603245
605153
|
this.updateTelegramParticipantProfile(sessionKey, msg, text);
|
|
603246
605154
|
this.updateTelegramMemoryCards(sessionKey, entry);
|
|
603247
605155
|
try {
|
|
@@ -603261,12 +605169,12 @@ ${mediaContext}` : ""
|
|
|
603261
605169
|
this.saveTelegramConversationState(sessionKey);
|
|
603262
605170
|
}
|
|
603263
605171
|
recordTelegramAssistantMessage(msg, text, mode, options2 = {}) {
|
|
603264
|
-
const
|
|
603265
|
-
if (!
|
|
605172
|
+
const clean5 = stripTelegramHiddenThinking(text).trim();
|
|
605173
|
+
if (!clean5) return;
|
|
603266
605174
|
const sessionKey = this.sessionKeyForMessage(msg);
|
|
603267
605175
|
const entry = {
|
|
603268
605176
|
role: "assistant",
|
|
603269
|
-
text:
|
|
605177
|
+
text: clean5,
|
|
603270
605178
|
mode,
|
|
603271
605179
|
chatId: msg.chatId,
|
|
603272
605180
|
speaker: this.state.botUsername ? `@${this.state.botUsername}` : "Assistant",
|
|
@@ -603277,16 +605185,17 @@ ${mediaContext}` : ""
|
|
|
603277
605185
|
chatTitle: msg.chatTitle
|
|
603278
605186
|
};
|
|
603279
605187
|
this.recordChatHistory(sessionKey, entry);
|
|
605188
|
+
this.upsertTelegramReflectionHistoryEntry(sessionKey, entry);
|
|
603280
605189
|
this.stimulation.recordAgentOutput(sessionKey);
|
|
603281
605190
|
this.updateTelegramMemoryCards(sessionKey, entry);
|
|
603282
605191
|
try {
|
|
603283
605192
|
updateScopedPersonality(this.telegramPersonalityScope(sessionKey, msg), {
|
|
603284
605193
|
speaker: entry.speaker || "Assistant",
|
|
603285
|
-
text:
|
|
605194
|
+
text: clean5,
|
|
603286
605195
|
role: "assistant",
|
|
603287
605196
|
mode,
|
|
603288
605197
|
ts: entry.ts,
|
|
603289
|
-
toneTags: inferTelegramToneTags(
|
|
605198
|
+
toneTags: inferTelegramToneTags(clean5)
|
|
603290
605199
|
});
|
|
603291
605200
|
} catch {
|
|
603292
605201
|
}
|
|
@@ -603354,7 +605263,7 @@ ${mediaContext}` : ""
|
|
|
603354
605263
|
}
|
|
603355
605264
|
const matchingEntry = mediaEntries.find((entry) => {
|
|
603356
605265
|
if (resolve41(entry.localPath) === resolve41(raw)) return true;
|
|
603357
|
-
if (
|
|
605266
|
+
if (basename27(entry.localPath) === raw) return true;
|
|
603358
605267
|
if (entry.fileUniqueId === raw || entry.fileId === raw) return true;
|
|
603359
605268
|
if (entry.messageId && String(entry.messageId) === raw) return true;
|
|
603360
605269
|
return false;
|
|
@@ -603390,7 +605299,7 @@ ${mediaContext}` : ""
|
|
|
603390
605299
|
}
|
|
603391
605300
|
return entries.find((entry2) => {
|
|
603392
605301
|
if (resolve41(entry2.localPath) === resolve41(ref)) return true;
|
|
603393
|
-
if (
|
|
605302
|
+
if (basename27(entry2.localPath) === ref) return true;
|
|
603394
605303
|
if (entry2.fileUniqueId === ref || entry2.fileId === ref) return true;
|
|
603395
605304
|
if (entry2.messageId && String(entry2.messageId) === ref) return true;
|
|
603396
605305
|
return false;
|
|
@@ -603418,7 +605327,7 @@ ${mediaContext}` : ""
|
|
|
603418
605327
|
caption: entry.caption
|
|
603419
605328
|
},
|
|
603420
605329
|
modality,
|
|
603421
|
-
label: `Telegram message_id ${entry.messageId || "unknown"} ${
|
|
605330
|
+
label: `Telegram message_id ${entry.messageId || "unknown"} ${basename27(entry.localPath)}`,
|
|
603422
605331
|
extractedContent: entry.extractedContent
|
|
603423
605332
|
};
|
|
603424
605333
|
}
|
|
@@ -603493,7 +605402,7 @@ ${mediaContext}` : ""
|
|
|
603493
605402
|
const titleTags = tags.slice(0, 4);
|
|
603494
605403
|
const title = titleTags.length > 0 ? `${speaker} / ${titleTags.join(" ")}` : `${speaker} / conversation`;
|
|
603495
605404
|
const card = {
|
|
603496
|
-
id:
|
|
605405
|
+
id: createHash23("sha1").update(`${sessionKey}:${now}:${speaker}:${text}`).digest("hex").slice(0, 12),
|
|
603497
605406
|
title,
|
|
603498
605407
|
notes: [],
|
|
603499
605408
|
tags: [],
|
|
@@ -603624,7 +605533,7 @@ ${cardLines.join("\n")}`);
|
|
|
603624
605533
|
const caption = entry.caption ? ` caption:${truncateTelegramContextLine(entry.caption, 120)}` : "";
|
|
603625
605534
|
const extracted = entry.extractedContent ? `
|
|
603626
605535
|
${truncateTelegramContextLine(entry.extractedContent.replace(/\s+/g, " "), 220)}` : "";
|
|
603627
|
-
return `- message_id ${entry.messageId}${replyMark}: ${kind}; path ${entry.localPath}; file ${
|
|
605536
|
+
return `- message_id ${entry.messageId}${replyMark}: ${kind}; path ${entry.localPath}; file ${basename27(entry.localPath)}${caption}${extracted}`;
|
|
603628
605537
|
});
|
|
603629
605538
|
sections.push([
|
|
603630
605539
|
"### Recent Chat Media",
|
|
@@ -603965,7 +605874,7 @@ ${list}` : "No shared group target is currently known for this sender. Ask in th
|
|
|
603965
605874
|
}
|
|
603966
605875
|
telegramRunnerStateDir(sessionKey) {
|
|
603967
605876
|
if (!this.repoRoot) return void 0;
|
|
603968
|
-
const safe =
|
|
605877
|
+
const safe = createHash23("sha1").update(sessionKey).digest("hex").slice(0, 20);
|
|
603969
605878
|
return join123(this.repoRoot, ".omnius", "telegram-runner-state", safe);
|
|
603970
605879
|
}
|
|
603971
605880
|
buildTelegramAdminOverviewContext(currentSessionKey) {
|
|
@@ -604325,6 +606234,11 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
604325
606234
|
await this.replyWithTelegramHelp(msg, isAdmin);
|
|
604326
606235
|
return;
|
|
604327
606236
|
}
|
|
606237
|
+
const telegramSlash = this.telegramSlashName(normalizedCommandText);
|
|
606238
|
+
if (msg.text.trim().startsWith("/") && TELEGRAM_REFLECTION_SLASH_COMMANDS.has(telegramSlash)) {
|
|
606239
|
+
await this.handleTelegramReflectionSlash(msg, normalizedCommandText);
|
|
606240
|
+
return;
|
|
606241
|
+
}
|
|
604328
606242
|
if (!this.agentConfig || !this.repoRoot) {
|
|
604329
606243
|
this.onMessage(msg);
|
|
604330
606244
|
return;
|
|
@@ -604332,7 +606246,6 @@ ${TELEGRAM_PUBLIC_ORCHESTRATOR_CONTRACT}`);
|
|
|
604332
606246
|
const toolContext = this.resolveToolContext(msg, isAdmin);
|
|
604333
606247
|
const isAdminDM = toolContext === "telegram-admin-dm";
|
|
604334
606248
|
const sessionKey = this.sessionKeyForMessage(msg);
|
|
604335
|
-
const telegramSlash = this.telegramSlashName(normalizedCommandText);
|
|
604336
606249
|
if (msg.text.trim().startsWith("/") && TELEGRAM_REMINDER_SLASH_COMMANDS.has(telegramSlash)) {
|
|
604337
606250
|
await this.handleTelegramReminderSlash(msg, normalizedCommandText, toolContext);
|
|
604338
606251
|
return;
|
|
@@ -604897,12 +606810,12 @@ ${conversationStream}`
|
|
|
604897
606810
|
}
|
|
604898
606811
|
retainTelegramVisibleReplyDraft(subAgent, draft, streamToolNames = subAgent.currentStreamToolNames) {
|
|
604899
606812
|
if (subAgent.visibleReplyText) return;
|
|
604900
|
-
const
|
|
604901
|
-
if (!
|
|
606813
|
+
const clean5 = cleanTelegramVisibleReply(draft);
|
|
606814
|
+
if (!clean5) return;
|
|
604902
606815
|
const toolNames = [...streamToolNames];
|
|
604903
606816
|
const hasNonCompletionTool = toolNames.some((name10) => name10 !== "task_complete");
|
|
604904
606817
|
if (hasNonCompletionTool) return;
|
|
604905
|
-
subAgent.visibleReplyText =
|
|
606818
|
+
subAgent.visibleReplyText = clean5;
|
|
604906
606819
|
}
|
|
604907
606820
|
retainTelegramVisibleReplyFromCompletedStream(subAgent) {
|
|
604908
606821
|
this.retainTelegramVisibleReplyDraft(
|
|
@@ -605685,6 +607598,7 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
605685
607598
|
return new IdentityMemoryTool(repoRoot, {
|
|
605686
607599
|
sourceSurface: "telegram",
|
|
605687
607600
|
scope,
|
|
607601
|
+
sessionId: currentMsg ? this.sessionKeyForMessage(currentMsg) : chatId !== void 0 ? `chat:${String(chatId)}` : void 0,
|
|
605688
607602
|
sender: currentMsg ? this.telegramMemorySenderFromMessage(currentMsg) : void 0,
|
|
605689
607603
|
message: message2,
|
|
605690
607604
|
replyTo: currentMsg ? this.telegramMemoryReplyRef(currentMsg) : void 0,
|
|
@@ -605720,7 +607634,7 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
605720
607634
|
`${index + 1}. message_id ${entry.messageId || "unknown"}`,
|
|
605721
607635
|
currentMsg?.replyToMessageId === entry.messageId ? "replied-to" : "",
|
|
605722
607636
|
telegramCachedMediaIsImage(entry) ? "image" : telegramCachedMediaIsPdf(entry) ? "pdf" : telegramCachedMediaIsAudio(entry) ? "audio" : telegramCachedMediaIsVideo(entry) ? "video" : entry.mediaType,
|
|
605723
|
-
`file=${
|
|
607637
|
+
`file=${basename27(entry.localPath)}`,
|
|
605724
607638
|
`path=${entry.localPath}`,
|
|
605725
607639
|
entry.caption ? `caption=${truncateTelegramContextLine(entry.caption, 140)}` : ""
|
|
605726
607640
|
].filter(Boolean);
|
|
@@ -605832,8 +607746,8 @@ Scoped workspace: ${scopedRoot}`,
|
|
|
605832
607746
|
bridge.rememberTelegramDeliveredArtifactForMessage(currentMsg, file.logicalPath ?? file.path);
|
|
605833
607747
|
return {
|
|
605834
607748
|
success: true,
|
|
605835
|
-
output: `Sent Telegram file: ${
|
|
605836
|
-
llmContent: `Sent ${
|
|
607749
|
+
output: `Sent Telegram file: ${basename27(file.path)} as ${kind} to ${String(target.chatId)}${messageId ? ` (message_id ${messageId})` : ""}`,
|
|
607750
|
+
llmContent: `Sent ${basename27(file.path)} to Telegram as ${kind}.`,
|
|
605837
607751
|
durationMs: performance.now() - start2,
|
|
605838
607752
|
mutated: false,
|
|
605839
607753
|
mutatedFiles: []
|
|
@@ -606039,15 +607953,43 @@ ${visionContext}]`;
|
|
|
606039
607953
|
} else {
|
|
606040
607954
|
description = `[${sourceLabel}image received and saved to ${localPath}${caption ? ` — caption: "${caption}"` : ""}. You can use image_read, ocr, or vision tools to analyze it.]`;
|
|
606041
607955
|
}
|
|
607956
|
+
const ingestPayload = this.telegramMemoryIngestPayload(msg, media, localPath, source, cacheEntry.extractedContent);
|
|
607957
|
+
let visualIdentityContext = "";
|
|
607958
|
+
let ingestReachedDaemon = false;
|
|
606042
607959
|
try {
|
|
606043
|
-
await fetch("http://127.0.0.1:11435/v1/memory/ingest", {
|
|
607960
|
+
const ingestResponse = await fetch("http://127.0.0.1:11435/v1/memory/ingest", {
|
|
606044
607961
|
method: "POST",
|
|
606045
607962
|
headers: { "Content-Type": "application/json" },
|
|
606046
|
-
body: JSON.stringify(
|
|
607963
|
+
body: JSON.stringify(ingestPayload),
|
|
606047
607964
|
signal: AbortSignal.timeout(2e3)
|
|
606048
607965
|
});
|
|
607966
|
+
ingestReachedDaemon = ingestResponse.ok;
|
|
607967
|
+
if (ingestResponse.ok) {
|
|
607968
|
+
const ingested = await ingestResponse.json().catch(() => null);
|
|
607969
|
+
const block = ingested?.visualIdentity?.contextBlock;
|
|
607970
|
+
if (typeof block === "string" && block.trim()) visualIdentityContext = block.trim();
|
|
607971
|
+
}
|
|
606049
607972
|
} catch {
|
|
606050
607973
|
}
|
|
607974
|
+
if (!ingestReachedDaemon && this.repoRoot) {
|
|
607975
|
+
try {
|
|
607976
|
+
const association = await associateVisualIdentityFromImage({
|
|
607977
|
+
repoRoot: this.repoRoot,
|
|
607978
|
+
imagePath: localPath,
|
|
607979
|
+
sourceSurface: "telegram",
|
|
607980
|
+
scope: ingestPayload["scope"],
|
|
607981
|
+
sender: ingestPayload["sender"],
|
|
607982
|
+
message: ingestPayload["message"],
|
|
607983
|
+
replyTo: ingestPayload["replyTo"],
|
|
607984
|
+
sessionId: typeof ingestPayload["sessionId"] === "string" ? ingestPayload["sessionId"] : this.sessionKeyForMessage(msg),
|
|
607985
|
+
media: ingestPayload["media"],
|
|
607986
|
+
extractedContent: cacheEntry.extractedContent
|
|
607987
|
+
});
|
|
607988
|
+
if (association.contextBlock) visualIdentityContext = association.contextBlock;
|
|
607989
|
+
} catch {
|
|
607990
|
+
}
|
|
607991
|
+
}
|
|
607992
|
+
description = appendMediaContextBlock(description, visualIdentityContext);
|
|
606051
607993
|
} else if (type === "audio" || type === "voice") {
|
|
606052
607994
|
let transcription = null;
|
|
606053
607995
|
try {
|
|
@@ -606221,7 +608163,7 @@ ${text}`.trim());
|
|
|
606221
608163
|
if (!existsSync108(media.value)) throw new Error(`File does not exist: ${media.value}`);
|
|
606222
608164
|
const buffer2 = readFileSync88(media.value);
|
|
606223
608165
|
const boundary = `----omnius-media-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
606224
|
-
const filename =
|
|
608166
|
+
const filename = basename27(media.value);
|
|
606225
608167
|
const contentType = mimeForPath(media.value, media.kind);
|
|
606226
608168
|
const parts = [];
|
|
606227
608169
|
const addField = (name10, value2) => {
|
|
@@ -606326,7 +608268,7 @@ Content-Type: ${contentType}\r
|
|
|
606326
608268
|
continue;
|
|
606327
608269
|
}
|
|
606328
608270
|
const buffer2 = readFileSync88(pathOrFileId);
|
|
606329
|
-
const filename =
|
|
608271
|
+
const filename = basename27(pathOrFileId);
|
|
606330
608272
|
parts.push(Buffer.from(`--${boundary}\r
|
|
606331
608273
|
`));
|
|
606332
608274
|
parts.push(Buffer.from(
|
|
@@ -606356,11 +608298,11 @@ Content-Type: ${mimeForPath(pathOrFileId, field === "photo" ? "image" : "video")
|
|
|
606356
608298
|
* Telegram accepts @botusername in chat_id for the supported bot-to-bot subset.
|
|
606357
608299
|
*/
|
|
606358
608300
|
async sendMessageToBot(username, text) {
|
|
606359
|
-
const
|
|
606360
|
-
if (!/^[A-Za-z0-9_]{5,32}$/.test(
|
|
608301
|
+
const clean5 = username.trim().replace(/^@/, "");
|
|
608302
|
+
if (!/^[A-Za-z0-9_]{5,32}$/.test(clean5)) {
|
|
606361
608303
|
throw new Error("Expected a Telegram bot username (5-32 chars, letters/numbers/underscore).");
|
|
606362
608304
|
}
|
|
606363
|
-
return this.sendMessage(`@${
|
|
608305
|
+
return this.sendMessage(`@${clean5}`, text);
|
|
606364
608306
|
}
|
|
606365
608307
|
async setMyCommands(commands) {
|
|
606366
608308
|
const apiCommands = commands.map((cmd) => ({
|
|
@@ -607390,7 +609332,7 @@ __export(projects_exports, {
|
|
|
607390
609332
|
});
|
|
607391
609333
|
import { readFileSync as readFileSync90, writeFileSync as writeFileSync59, mkdirSync as mkdirSync65, existsSync as existsSync110, statSync as statSync37, renameSync as renameSync6 } from "node:fs";
|
|
607392
609334
|
import { homedir as homedir37 } from "node:os";
|
|
607393
|
-
import { basename as
|
|
609335
|
+
import { basename as basename28, join as join125, resolve as resolve42 } from "node:path";
|
|
607394
609336
|
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
607395
609337
|
function readAll2() {
|
|
607396
609338
|
try {
|
|
@@ -607438,7 +609380,7 @@ function registerProject(root, pid) {
|
|
|
607438
609380
|
} else {
|
|
607439
609381
|
entry = {
|
|
607440
609382
|
root: canonical,
|
|
607441
|
-
name:
|
|
609383
|
+
name: basename28(canonical) || canonical,
|
|
607442
609384
|
firstSeen: now,
|
|
607443
609385
|
lastSeen: now,
|
|
607444
609386
|
pid: pid ?? null,
|
|
@@ -608164,24 +610106,24 @@ function stripMappedPrefix(ip) {
|
|
|
608164
610106
|
}
|
|
608165
610107
|
function isLoopbackIP(ip) {
|
|
608166
610108
|
if (!ip) return false;
|
|
608167
|
-
const
|
|
608168
|
-
if (
|
|
608169
|
-
if (/^127\./.test(
|
|
610109
|
+
const clean5 = stripMappedPrefix(ip);
|
|
610110
|
+
if (clean5 === "::1") return true;
|
|
610111
|
+
if (/^127\./.test(clean5)) return true;
|
|
608170
610112
|
return false;
|
|
608171
610113
|
}
|
|
608172
610114
|
function isPrivateIP(ip) {
|
|
608173
610115
|
if (!ip) return false;
|
|
608174
|
-
const
|
|
608175
|
-
if (/^10\./.test(
|
|
608176
|
-
if (/^192\.168\./.test(
|
|
608177
|
-
const m2 = /^172\.(\d{1,3})\./.exec(
|
|
610116
|
+
const clean5 = stripMappedPrefix(ip);
|
|
610117
|
+
if (/^10\./.test(clean5)) return true;
|
|
610118
|
+
if (/^192\.168\./.test(clean5)) return true;
|
|
610119
|
+
const m2 = /^172\.(\d{1,3})\./.exec(clean5);
|
|
608178
610120
|
if (m2) {
|
|
608179
610121
|
const second3 = parseInt(m2[1], 10);
|
|
608180
610122
|
if (second3 >= 16 && second3 <= 31) return true;
|
|
608181
610123
|
}
|
|
608182
|
-
if (/^169\.254\./.test(
|
|
608183
|
-
if (/^f[cd][0-9a-f]{2}:/i.test(
|
|
608184
|
-
if (/^fe[89ab][0-9a-f]:/i.test(
|
|
610124
|
+
if (/^169\.254\./.test(clean5)) return true;
|
|
610125
|
+
if (/^f[cd][0-9a-f]{2}:/i.test(clean5)) return true;
|
|
610126
|
+
if (/^fe[89ab][0-9a-f]:/i.test(clean5)) return true;
|
|
608185
610127
|
return false;
|
|
608186
610128
|
}
|
|
608187
610129
|
function isAllowedIP(ip, mode) {
|
|
@@ -608207,14 +610149,14 @@ var init_access_policy = __esm({
|
|
|
608207
610149
|
});
|
|
608208
610150
|
|
|
608209
610151
|
// packages/cli/src/api/project-preferences.ts
|
|
608210
|
-
import { createHash as
|
|
610152
|
+
import { createHash as createHash24 } from "node:crypto";
|
|
608211
610153
|
import { existsSync as existsSync111, mkdirSync as mkdirSync66, readFileSync as readFileSync91, renameSync as renameSync7, writeFileSync as writeFileSync60, unlinkSync as unlinkSync23 } from "node:fs";
|
|
608212
610154
|
import { homedir as homedir38 } from "node:os";
|
|
608213
610155
|
import { join as join126, resolve as resolve43 } from "node:path";
|
|
608214
610156
|
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
608215
610157
|
function projectKey(root) {
|
|
608216
610158
|
const canonical = resolve43(root);
|
|
608217
|
-
return
|
|
610159
|
+
return createHash24("sha256").update(canonical).digest("hex").slice(0, 16);
|
|
608218
610160
|
}
|
|
608219
610161
|
function projectDir(root) {
|
|
608220
610162
|
return join126(PROJECTS_DIR, projectKey(root));
|
|
@@ -608306,7 +610248,7 @@ __export(voicechat_exports, {
|
|
|
608306
610248
|
VoiceChatSession: () => VoiceChatSession
|
|
608307
610249
|
});
|
|
608308
610250
|
import { EventEmitter as EventEmitter11 } from "node:events";
|
|
608309
|
-
function
|
|
610251
|
+
function clamp019(x) {
|
|
608310
610252
|
return x < 0 ? 0 : x > 1 ? 1 : x;
|
|
608311
610253
|
}
|
|
608312
610254
|
function alnumRatio(s2) {
|
|
@@ -608345,9 +610287,9 @@ function computeSignalFromText(text, confidence2) {
|
|
|
608345
610287
|
else score = 0.15;
|
|
608346
610288
|
score -= repeatingCharPenalty(t2) * 0.4;
|
|
608347
610289
|
if (typeof confidence2 === "number" && !Number.isNaN(confidence2)) {
|
|
608348
|
-
score = 0.7 * score + 0.3 *
|
|
610290
|
+
score = 0.7 * score + 0.3 * clamp019(confidence2);
|
|
608349
610291
|
}
|
|
608350
|
-
return
|
|
610292
|
+
return clamp019(score);
|
|
608351
610293
|
}
|
|
608352
610294
|
function truncateForLog(s2, n2) {
|
|
608353
610295
|
return s2.length <= n2 ? s2 : s2.slice(0, n2 - 1) + "…";
|
|
@@ -608617,7 +610559,7 @@ Rules:
|
|
|
608617
610559
|
}, MAX_SEGMENT_MS);
|
|
608618
610560
|
}
|
|
608619
610561
|
this.captureBuffer = text;
|
|
608620
|
-
this.lastSignalScore = typeof snr === "number" && !Number.isNaN(snr) ?
|
|
610562
|
+
this.lastSignalScore = typeof snr === "number" && !Number.isNaN(snr) ? clamp019(snr) : computeSignalFromText(text, confidence2);
|
|
608621
610563
|
this.emit("snr", { score: this.lastSignalScore });
|
|
608622
610564
|
this.onPartialTranscript(text);
|
|
608623
610565
|
if (this.silenceTimer) clearTimeout(this.silenceTimer);
|
|
@@ -609392,7 +611334,7 @@ var init_disk_task_output = __esm({
|
|
|
609392
611334
|
});
|
|
609393
611335
|
|
|
609394
611336
|
// packages/cli/src/api/http.ts
|
|
609395
|
-
import { createHash as
|
|
611337
|
+
import { createHash as createHash25 } from "node:crypto";
|
|
609396
611338
|
function problemDetails(opts) {
|
|
609397
611339
|
const p2 = {
|
|
609398
611340
|
type: opts.type ?? "about:blank",
|
|
@@ -609455,7 +611397,7 @@ function paginated(items, page2, total) {
|
|
|
609455
611397
|
}
|
|
609456
611398
|
function computeEtag(payload) {
|
|
609457
611399
|
const json = typeof payload === "string" ? payload : JSON.stringify(payload);
|
|
609458
|
-
const hash =
|
|
611400
|
+
const hash = createHash25("sha1").update(json).digest("hex").slice(0, 16);
|
|
609459
611401
|
return `W/"${hash}"`;
|
|
609460
611402
|
}
|
|
609461
611403
|
function checkNotModified(req2, res, etag) {
|
|
@@ -616604,13 +618546,20 @@ async function sendMessage() {
|
|
|
616604
618546
|
showStreamingIndicator(msgDiv, 'thinking');
|
|
616605
618547
|
|
|
616606
618548
|
try {
|
|
618549
|
+
const attachmentContextBlock = _attachments.length > 0
|
|
618550
|
+
? await uploadChatAttachments(chatSessionId)
|
|
618551
|
+
: '';
|
|
618552
|
+
|
|
616607
618553
|
// Prepend context files as a FILES block so the agent can read them
|
|
616608
618554
|
// without having to guess paths. The user picked these via right-click
|
|
616609
618555
|
// "Add to context" on the workspace tree.
|
|
616610
618556
|
let messageWithContext = sendText;
|
|
618557
|
+
if (attachmentContextBlock) {
|
|
618558
|
+
messageWithContext = attachmentContextBlock + '\\n\\n' + messageWithContext;
|
|
618559
|
+
}
|
|
616611
618560
|
if (contextFiles.length > 0) {
|
|
616612
618561
|
const filesBlock = 'FILES IN CONTEXT:\\n' + contextFiles.map(p => ' - ' + p).join('\\n') + '\\n\\n';
|
|
616613
|
-
messageWithContext = filesBlock +
|
|
618562
|
+
messageWithContext = filesBlock + messageWithContext;
|
|
616614
618563
|
}
|
|
616615
618564
|
|
|
616616
618565
|
// FRESH-SESSION: pull the one-shot fresh flag the newChatSession()
|
|
@@ -621863,6 +623812,51 @@ function _removeAttachment(i) {
|
|
|
621863
623812
|
_renderAttachChips();
|
|
621864
623813
|
}
|
|
621865
623814
|
|
|
623815
|
+
function _fileToBase64(file) {
|
|
623816
|
+
return new Promise((resolve, reject) => {
|
|
623817
|
+
const reader = new FileReader();
|
|
623818
|
+
reader.onload = () => {
|
|
623819
|
+
const raw = String(reader.result || '');
|
|
623820
|
+
const comma = raw.indexOf(',');
|
|
623821
|
+
resolve(comma >= 0 ? raw.slice(comma + 1) : raw);
|
|
623822
|
+
};
|
|
623823
|
+
reader.onerror = () => reject(reader.error || new Error('file_read_failed'));
|
|
623824
|
+
reader.readAsDataURL(file);
|
|
623825
|
+
});
|
|
623826
|
+
}
|
|
623827
|
+
|
|
623828
|
+
async function uploadChatAttachments(sessionId) {
|
|
623829
|
+
if (!_attachments.length) return '';
|
|
623830
|
+
const blocks = [];
|
|
623831
|
+
for (const attachment of _attachments) {
|
|
623832
|
+
try {
|
|
623833
|
+
const base64 = await _fileToBase64(attachment.file);
|
|
623834
|
+
const response = await fetch('/v1/chat/attachments', {
|
|
623835
|
+
method: 'POST',
|
|
623836
|
+
headers: headers(),
|
|
623837
|
+
body: JSON.stringify({
|
|
623838
|
+
session_id: sessionId || '',
|
|
623839
|
+
filename: attachment.name,
|
|
623840
|
+
mimeType: attachment.file && attachment.file.type ? attachment.file.type : '',
|
|
623841
|
+
base64,
|
|
623842
|
+
}),
|
|
623843
|
+
});
|
|
623844
|
+
if (!response.ok) {
|
|
623845
|
+
blocks.push('GUI attachment failed: ' + attachment.name);
|
|
623846
|
+
continue;
|
|
623847
|
+
}
|
|
623848
|
+
const data = await response.json();
|
|
623849
|
+
blocks.push(data.contextBlock || ('GUI attachment saved: ' + (data.path || attachment.name)));
|
|
623850
|
+
} catch (err) {
|
|
623851
|
+
blocks.push('GUI attachment failed: ' + attachment.name + ' (' + ((err && err.message) ? err.message : String(err)) + ')');
|
|
623852
|
+
}
|
|
623853
|
+
}
|
|
623854
|
+
_attachments = [];
|
|
623855
|
+
_renderAttachChips();
|
|
623856
|
+
if (!blocks.length) return '';
|
|
623857
|
+
return 'GUI ATTACHMENTS:\\n' + blocks.map((block) => String(block).split('\\n').map((line) => ' ' + line).join('\\n')).join('\\n\\n');
|
|
623858
|
+
}
|
|
623859
|
+
|
|
621866
623860
|
// Drag & drop on the input row
|
|
621867
623861
|
(function _wireDropZone() {
|
|
621868
623862
|
const row = document.getElementById('input-row');
|
|
@@ -623458,7 +625452,7 @@ __export(embedding_workers_exports, {
|
|
|
623458
625452
|
startEmbeddingWorkers: () => startEmbeddingWorkers,
|
|
623459
625453
|
stopEmbeddingWorkers: () => stopEmbeddingWorkers
|
|
623460
625454
|
});
|
|
623461
|
-
import { basename as
|
|
625455
|
+
import { basename as basename29, join as join136 } from "node:path";
|
|
623462
625456
|
function startEmbeddingWorkers(opts) {
|
|
623463
625457
|
if (_running) return;
|
|
623464
625458
|
_running = true;
|
|
@@ -623524,7 +625518,7 @@ async function runEmbeddingTask(modality, episodeId, taskId, opts) {
|
|
|
623524
625518
|
try {
|
|
623525
625519
|
if (!_aligner) {
|
|
623526
625520
|
const stateRoot = process.env.OMNIUS_DIR || process.cwd();
|
|
623527
|
-
const omniusDir =
|
|
625521
|
+
const omniusDir = basename29(stateRoot) === ".omnius" ? stateRoot : join136(stateRoot, ".omnius");
|
|
623528
625522
|
const memDir = join136(omniusDir, "memory");
|
|
623529
625523
|
_aligner = new EmbeddingAligner(
|
|
623530
625524
|
`${modality}-${emb.length}`,
|
|
@@ -623645,7 +625639,7 @@ import { homedir as homedir45 } from "node:os";
|
|
|
623645
625639
|
import { spawn as spawn29, execSync as execSync57 } from "node:child_process";
|
|
623646
625640
|
import { mkdirSync as mkdirSync74, writeFileSync as writeFileSync66, readFileSync as readFileSync99, readdirSync as readdirSync42, existsSync as existsSync122, watch as fsWatch3, renameSync as renameSync8, unlinkSync as unlinkSync25 } from "node:fs";
|
|
623647
625641
|
import { randomBytes as randomBytes24, randomUUID as randomUUID16 } from "node:crypto";
|
|
623648
|
-
import { createHash as
|
|
625642
|
+
import { createHash as createHash27 } from "node:crypto";
|
|
623649
625643
|
function memoryDbPaths3(baseDir = process.cwd()) {
|
|
623650
625644
|
const dir = join137(baseDir, ".omnius");
|
|
623651
625645
|
return {
|
|
@@ -629518,7 +631512,7 @@ function listScheduledTasks() {
|
|
|
629518
631512
|
const schedule = String(t2?.schedule || t2?.cron || t2?.when || "");
|
|
629519
631513
|
const enabled2 = typeof t2?.enabled === "boolean" ? t2.enabled : true;
|
|
629520
631514
|
const realId = typeof t2?.id === "string" && t2.id ? t2.id : null;
|
|
629521
|
-
const fallbackId =
|
|
631515
|
+
const fallbackId = createHash27("sha1").update(`${file}#${i2}`).digest("hex").slice(0, 16);
|
|
629522
631516
|
const uid = realId || fallbackId;
|
|
629523
631517
|
const key = `${uid}`;
|
|
629524
631518
|
if (seen.has(key)) return;
|
|
@@ -629635,8 +631629,8 @@ function deleteScheduledById(id) {
|
|
|
629635
631629
|
if (id) candidates.push(id);
|
|
629636
631630
|
if (typeof entry?.id === "string" && entry.id && !candidates.includes(entry.id)) candidates.push(entry.id);
|
|
629637
631631
|
try {
|
|
629638
|
-
const { createHash:
|
|
629639
|
-
const fallback =
|
|
631632
|
+
const { createHash: createHash28 } = require4("node:crypto");
|
|
631633
|
+
const fallback = createHash28("sha1").update(`${target.file}#${target.index}`).digest("hex").slice(0, 16);
|
|
629640
631634
|
if (!candidates.includes(fallback)) candidates.push(fallback);
|
|
629641
631635
|
} catch {
|
|
629642
631636
|
}
|
|
@@ -630391,6 +632385,10 @@ function startApiServer(options2 = {}) {
|
|
|
630391
632385
|
handleMemoryIngest(req2, res, ollamaUrl);
|
|
630392
632386
|
return;
|
|
630393
632387
|
}
|
|
632388
|
+
if (req2.method === "POST" && url.pathname === "/v1/chat/attachments") {
|
|
632389
|
+
handleChatAttachmentUpload(req2, res);
|
|
632390
|
+
return;
|
|
632391
|
+
}
|
|
630394
632392
|
if (req2.method === "GET" && url.pathname === "/v1/memory/entities") {
|
|
630395
632393
|
handleEntitiesList(req2, res);
|
|
630396
632394
|
return;
|
|
@@ -630948,6 +632946,126 @@ async function handleAudioEmbed(req2, res) {
|
|
|
630948
632946
|
jsonResponse(res, 400, { error: "bad_request", message: err instanceof Error ? err.message : String(err) });
|
|
630949
632947
|
}
|
|
630950
632948
|
}
|
|
632949
|
+
async function handleChatAttachmentUpload(req2, res) {
|
|
632950
|
+
try {
|
|
632951
|
+
const body = await parseJsonBody(req2);
|
|
632952
|
+
if (!body || typeof body !== "object") {
|
|
632953
|
+
jsonResponse(res, 400, { error: "bad_request" });
|
|
632954
|
+
return;
|
|
632955
|
+
}
|
|
632956
|
+
const b = body;
|
|
632957
|
+
const filename = typeof b.filename === "string" && b.filename.trim() ? b.filename.trim() : `attachment-${Date.now()}.bin`;
|
|
632958
|
+
const base642 = typeof b.base64 === "string" ? b.base64 : "";
|
|
632959
|
+
if (!base642) {
|
|
632960
|
+
jsonResponse(res, 400, { error: "missing_base64" });
|
|
632961
|
+
return;
|
|
632962
|
+
}
|
|
632963
|
+
const safeName2 = filename.replace(/[^a-zA-Z0-9._-]/g, "-").slice(0, 180) || `attachment-${Date.now()}.bin`;
|
|
632964
|
+
const dir = join137(process.cwd(), ".omnius", "gui-attachments");
|
|
632965
|
+
mkdirSync74(dir, { recursive: true });
|
|
632966
|
+
const localPath = join137(dir, `${Date.now()}-${randomUUID16().slice(0, 8)}-${safeName2}`);
|
|
632967
|
+
writeFileSync66(localPath, Buffer.from(base642, "base64"));
|
|
632968
|
+
const mimeType = typeof b.mimeType === "string" ? b.mimeType : typeof b.mime_type === "string" ? b.mime_type : "";
|
|
632969
|
+
const isImage = mimeType.toLowerCase().startsWith("image/") || /\.(png|jpe?g|gif|webp|bmp|tiff?)$/i.test(safeName2);
|
|
632970
|
+
const sessionId = typeof b.sessionId === "string" ? b.sessionId : typeof b.session_id === "string" ? b.session_id : void 0;
|
|
632971
|
+
const scope = typeof b.scope === "object" && b.scope ? b.scope : { kind: "gui", id: sessionId || "web", title: "GUI session" };
|
|
632972
|
+
const sender = typeof b.sender === "object" && b.sender ? b.sender : { id: "gui-user", displayName: "GUI user" };
|
|
632973
|
+
const message2 = {
|
|
632974
|
+
id: typeof b.message_id === "string" || typeof b.message_id === "number" ? b.message_id : `attachment:${randomUUID16()}`,
|
|
632975
|
+
timestamp: Date.now(),
|
|
632976
|
+
text: typeof b.caption === "string" && b.caption.trim() ? b.caption.trim() : `GUI attachment: ${safeName2}`
|
|
632977
|
+
};
|
|
632978
|
+
const media = {
|
|
632979
|
+
path: localPath,
|
|
632980
|
+
mediaType: isImage ? "photo" : "document",
|
|
632981
|
+
mimeType: mimeType || void 0,
|
|
632982
|
+
caption: typeof b.caption === "string" ? b.caption : void 0
|
|
632983
|
+
};
|
|
632984
|
+
const modality = isImage ? "visual" : "text";
|
|
632985
|
+
const { EpisodeStore: EpisodeStore3, TemporalGraph: TemporalGraph3, MultimodalIdentityService: MultimodalIdentityService2 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
|
|
632986
|
+
const dbPaths = memoryDbPaths3(process.cwd());
|
|
632987
|
+
const graph = new TemporalGraph3(dbPaths.knowledge);
|
|
632988
|
+
const store2 = new EpisodeStore3(dbPaths.episodes, graph);
|
|
632989
|
+
let ingestId = "";
|
|
632990
|
+
try {
|
|
632991
|
+
const embeddings = {};
|
|
632992
|
+
if (isImage) {
|
|
632993
|
+
try {
|
|
632994
|
+
const provider = globalThis.__omniusVisionProvider;
|
|
632995
|
+
const emb = provider ? await provider({ path: localPath }) : null;
|
|
632996
|
+
if (emb) embeddings.imageClip = emb;
|
|
632997
|
+
} catch {
|
|
632998
|
+
}
|
|
632999
|
+
}
|
|
633000
|
+
const service = new MultimodalIdentityService2({ episodeStore: store2, graph });
|
|
633001
|
+
ingestId = service.ingest({
|
|
633002
|
+
sourceSurface: "gui",
|
|
633003
|
+
sessionId,
|
|
633004
|
+
scope,
|
|
633005
|
+
sender,
|
|
633006
|
+
message: message2,
|
|
633007
|
+
modality,
|
|
633008
|
+
content: `GUI attachment: ${safeName2}`,
|
|
633009
|
+
media,
|
|
633010
|
+
labels: [safeName2, typeof b.caption === "string" ? b.caption : ""].filter(Boolean),
|
|
633011
|
+
embeddings
|
|
633012
|
+
}).episodeId;
|
|
633013
|
+
} finally {
|
|
633014
|
+
store2.close();
|
|
633015
|
+
graph.close();
|
|
633016
|
+
}
|
|
633017
|
+
let visualIdentity = void 0;
|
|
633018
|
+
let contextBlock = [
|
|
633019
|
+
`GUI attachment saved: ${safeName2}`,
|
|
633020
|
+
`path: ${localPath}`,
|
|
633021
|
+
mimeType ? `mime_type: ${mimeType}` : ""
|
|
633022
|
+
].filter(Boolean).join("\n");
|
|
633023
|
+
if (isImage) {
|
|
633024
|
+
try {
|
|
633025
|
+
const { associateVisualIdentityFromImage: associateVisualIdentityFromImage2 } = await Promise.resolve().then(() => (init_visual_identity_association(), visual_identity_association_exports));
|
|
633026
|
+
const association = await associateVisualIdentityFromImage2({
|
|
633027
|
+
repoRoot: process.cwd(),
|
|
633028
|
+
imagePath: localPath,
|
|
633029
|
+
sourceSurface: "gui",
|
|
633030
|
+
scope,
|
|
633031
|
+
sender,
|
|
633032
|
+
message: message2,
|
|
633033
|
+
sessionId,
|
|
633034
|
+
media
|
|
633035
|
+
});
|
|
633036
|
+
visualIdentity = {
|
|
633037
|
+
matches: association.matches,
|
|
633038
|
+
recalledEpisodes: association.recalledEpisodes,
|
|
633039
|
+
committedEpisodeIds: association.committedEpisodeIds,
|
|
633040
|
+
contextBlock: association.contextBlock,
|
|
633041
|
+
degradedReason: association.degradedReason
|
|
633042
|
+
};
|
|
633043
|
+
if (association.contextBlock) contextBlock += `
|
|
633044
|
+
|
|
633045
|
+
${association.contextBlock}`;
|
|
633046
|
+
} catch (err) {
|
|
633047
|
+
visualIdentity = {
|
|
633048
|
+
matches: [],
|
|
633049
|
+
recalledEpisodes: [],
|
|
633050
|
+
committedEpisodeIds: [],
|
|
633051
|
+
contextBlock: "",
|
|
633052
|
+
degradedReason: err instanceof Error ? err.message : String(err)
|
|
633053
|
+
};
|
|
633054
|
+
}
|
|
633055
|
+
}
|
|
633056
|
+
jsonResponse(res, 200, {
|
|
633057
|
+
id: ingestId,
|
|
633058
|
+
path: localPath,
|
|
633059
|
+
filename: safeName2,
|
|
633060
|
+
mimeType,
|
|
633061
|
+
modality,
|
|
633062
|
+
contextBlock,
|
|
633063
|
+
visualIdentity
|
|
633064
|
+
});
|
|
633065
|
+
} catch (err) {
|
|
633066
|
+
jsonResponse(res, 400, { error: "bad_request", message: err instanceof Error ? err.message : String(err) });
|
|
633067
|
+
}
|
|
633068
|
+
}
|
|
630951
633069
|
async function handleMemoryIngest(req2, res, ollamaUrl) {
|
|
630952
633070
|
try {
|
|
630953
633071
|
const body = await parseJsonBody(req2);
|
|
@@ -630971,6 +633089,7 @@ async function handleMemoryIngest(req2, res, ollamaUrl) {
|
|
|
630971
633089
|
};
|
|
630972
633090
|
const media = Object.values(rawMedia).some((value2) => value2 != null && String(value2).trim() !== "") ? rawMedia : void 0;
|
|
630973
633091
|
const sourceSurface = String(b.sourceSurface || b.source_surface || "api");
|
|
633092
|
+
const sessionId = typeof b.sessionId === "string" ? b.sessionId : typeof b.session_id === "string" ? b.session_id : void 0;
|
|
630974
633093
|
const scope = typeof b.scope === "object" && b.scope ? b.scope : {
|
|
630975
633094
|
kind: b.scope_kind || (b.chat_type === "private" ? "private" : b.chat_id ? "group" : "global"),
|
|
630976
633095
|
id: String(b.scope_id || b.chat_id || sourceSurface),
|
|
@@ -631026,6 +633145,7 @@ async function handleMemoryIngest(req2, res, ollamaUrl) {
|
|
|
631026
633145
|
const service = new MultimodalIdentityService2({ episodeStore: epStore, graph: kg });
|
|
631027
633146
|
const result = service.ingest({
|
|
631028
633147
|
sourceSurface,
|
|
633148
|
+
sessionId,
|
|
631029
633149
|
scope,
|
|
631030
633150
|
sender,
|
|
631031
633151
|
message: message2,
|
|
@@ -631039,7 +633159,42 @@ async function handleMemoryIngest(req2, res, ollamaUrl) {
|
|
|
631039
633159
|
identityAssertions,
|
|
631040
633160
|
embeddings
|
|
631041
633161
|
});
|
|
631042
|
-
|
|
633162
|
+
let visualIdentity = void 0;
|
|
633163
|
+
if (modality === "visual" && mediaPath) {
|
|
633164
|
+
try {
|
|
633165
|
+
const { associateVisualIdentityFromImage: associateVisualIdentityFromImage2 } = await Promise.resolve().then(() => (init_visual_identity_association(), visual_identity_association_exports));
|
|
633166
|
+
const association = await associateVisualIdentityFromImage2({
|
|
633167
|
+
repoRoot: process.cwd(),
|
|
633168
|
+
imagePath: mediaPath,
|
|
633169
|
+
sourceSurface,
|
|
633170
|
+
scope,
|
|
633171
|
+
sender,
|
|
633172
|
+
message: message2,
|
|
633173
|
+
replyTo,
|
|
633174
|
+
sessionId,
|
|
633175
|
+
media,
|
|
633176
|
+
extractedContent: b.extracted_content || b.extractedContent,
|
|
633177
|
+
threshold: typeof b.threshold === "number" ? b.threshold : 0.5,
|
|
633178
|
+
limit: typeof b.limit === "number" ? b.limit : 5
|
|
633179
|
+
});
|
|
633180
|
+
visualIdentity = {
|
|
633181
|
+
matches: association.matches,
|
|
633182
|
+
recalledEpisodes: association.recalledEpisodes,
|
|
633183
|
+
committedEpisodeIds: association.committedEpisodeIds,
|
|
633184
|
+
contextBlock: association.contextBlock,
|
|
633185
|
+
degradedReason: association.degradedReason
|
|
633186
|
+
};
|
|
633187
|
+
} catch (err) {
|
|
633188
|
+
visualIdentity = {
|
|
633189
|
+
matches: [],
|
|
633190
|
+
recalledEpisodes: [],
|
|
633191
|
+
committedEpisodeIds: [],
|
|
633192
|
+
contextBlock: "",
|
|
633193
|
+
degradedReason: err instanceof Error ? err.message : String(err)
|
|
633194
|
+
};
|
|
633195
|
+
}
|
|
633196
|
+
}
|
|
633197
|
+
jsonResponse(res, 200, { id: result.episodeId, ...result, visualIdentity });
|
|
631043
633198
|
} catch (err) {
|
|
631044
633199
|
jsonResponse(res, 400, { error: "bad_request", message: err instanceof Error ? err.message : String(err) });
|
|
631045
633200
|
}
|
|
@@ -631690,6 +633845,7 @@ function buildSubAgentTools(repoRoot, config) {
|
|
|
631690
633845
|
id: process.env["OMNIUS_SESSION_ID"] || "terminal",
|
|
631691
633846
|
title: "TUI session"
|
|
631692
633847
|
},
|
|
633848
|
+
sessionId: process.env["OMNIUS_SESSION_ID"] || "terminal",
|
|
631693
633849
|
sender: { id: "local-user", displayName: "User" }
|
|
631694
633850
|
}),
|
|
631695
633851
|
new VideoUnderstandTool(repoRoot),
|
|
@@ -631842,6 +633998,7 @@ function buildTools(repoRoot, config, contextWindowSize, modelTier) {
|
|
|
631842
633998
|
id: process.env["OMNIUS_SESSION_ID"] || "terminal",
|
|
631843
633999
|
title: "TUI session"
|
|
631844
634000
|
},
|
|
634001
|
+
sessionId: process.env["OMNIUS_SESSION_ID"] || "terminal",
|
|
631845
634002
|
sender: { id: "local-user", displayName: "User" }
|
|
631846
634003
|
}),
|
|
631847
634004
|
new AsrListenTool(),
|
|
@@ -636637,8 +638794,28 @@ Log: ${nexusLogPath}`)
|
|
|
636637
638794
|
visionContext = formatImageContextPrefix2(ingressResult);
|
|
636638
638795
|
} catch {
|
|
636639
638796
|
}
|
|
638797
|
+
let visualIdentityContext = "";
|
|
638798
|
+
try {
|
|
638799
|
+
const association = await associateVisualIdentityFromImage({
|
|
638800
|
+
repoRoot,
|
|
638801
|
+
imagePath: pasted.path,
|
|
638802
|
+
sourceSurface: "tui",
|
|
638803
|
+
scope: {
|
|
638804
|
+
kind: "terminal",
|
|
638805
|
+
id: process.env["OMNIUS_SESSION_ID"] || "terminal",
|
|
638806
|
+
title: "TUI session"
|
|
638807
|
+
},
|
|
638808
|
+
sender: { id: "local-user", displayName: "User" },
|
|
638809
|
+
message: { timestamp: Date.now(), text: "User pasted a clipboard image." },
|
|
638810
|
+
sessionId: process.env["OMNIUS_SESSION_ID"] || "terminal",
|
|
638811
|
+
media: { path: pasted.path, mediaType: "photo", mimeType: pasted.mime },
|
|
638812
|
+
extractedContent: visionContext
|
|
638813
|
+
});
|
|
638814
|
+
visualIdentityContext = association.contextBlock;
|
|
638815
|
+
} catch {
|
|
638816
|
+
}
|
|
636640
638817
|
const asciiContext = await asciiContextPromise;
|
|
636641
|
-
const imageContext = [visionContext, asciiContext].filter(Boolean).join("\n\n");
|
|
638818
|
+
const imageContext = [visionContext, visualIdentityContext, asciiContext].filter(Boolean).join("\n\n");
|
|
636642
638819
|
if (activeTask) {
|
|
636643
638820
|
activeTask.runner.injectImage(
|
|
636644
638821
|
pasted.buffer.toString("base64"),
|
|
@@ -637094,9 +639271,9 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
637094
639271
|
return `Skill invoked: ${result.name}`;
|
|
637095
639272
|
}
|
|
637096
639273
|
const raw = captured.join("");
|
|
637097
|
-
const
|
|
637098
|
-
if (!
|
|
637099
|
-
return
|
|
639274
|
+
const clean5 = raw.replace(/\x1B\[[0-9;]*[A-Za-z]/g, "").replace(/\x1B\][^\x07]*\x07/g, "").replace(/\x1B[()][A-Z0-9]/g, "").replace(/\x1B\[?\??[0-9;]*[a-zA-Z]/g, "").replace(/\x1B/g, "").replace(/[─━│┃┌┐└┘├┤┬┴┼╔╗╚╝╠╣╦╩╬⎿⎾▕▏⏐]/g, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
639275
|
+
if (!clean5) return null;
|
|
639276
|
+
return clean5.length > 3900 ? clean5.slice(0, 3900) + "\n..." : clean5;
|
|
637100
639277
|
} catch (err) {
|
|
637101
639278
|
process.stdout.write = origWrite;
|
|
637102
639279
|
throw err;
|
|
@@ -638806,12 +640983,32 @@ Execute this skill now. Follow the behavioral guidance above.`;
|
|
|
638806
640983
|
"Shared image",
|
|
638807
640984
|
writeContent
|
|
638808
640985
|
);
|
|
640986
|
+
let visualIdentityContext = "";
|
|
640987
|
+
try {
|
|
640988
|
+
const association = await associateVisualIdentityFromImage({
|
|
640989
|
+
repoRoot,
|
|
640990
|
+
imagePath: imgPath,
|
|
640991
|
+
sourceSurface: "tui",
|
|
640992
|
+
scope: {
|
|
640993
|
+
kind: "terminal",
|
|
640994
|
+
id: process.env["OMNIUS_SESSION_ID"] || "terminal",
|
|
640995
|
+
title: "TUI session"
|
|
640996
|
+
},
|
|
640997
|
+
sender: { id: "local-user", displayName: "User" },
|
|
640998
|
+
message: { timestamp: Date.now(), text: `User shared image: ${cleanPath}` },
|
|
640999
|
+
sessionId: process.env["OMNIUS_SESSION_ID"] || "terminal",
|
|
641000
|
+
media: { path: imgPath, mediaType: "photo", mimeType: mime }
|
|
641001
|
+
});
|
|
641002
|
+
visualIdentityContext = association.contextBlock;
|
|
641003
|
+
} catch {
|
|
641004
|
+
}
|
|
641005
|
+
const combinedImageContext = [asciiContext, visualIdentityContext].filter(Boolean).join("\n\n");
|
|
638809
641006
|
activeTask.runner.injectImage(
|
|
638810
641007
|
base642,
|
|
638811
641008
|
mime,
|
|
638812
|
-
|
|
641009
|
+
combinedImageContext ? `User shared image: ${cleanPath}
|
|
638813
641010
|
|
|
638814
|
-
${
|
|
641011
|
+
${combinedImageContext}` : `User shared image: ${cleanPath}`
|
|
638815
641012
|
);
|
|
638816
641013
|
writeContent(() => renderUserInterrupt(`[Image: ${cleanPath}]`));
|
|
638817
641014
|
} catch {
|
|
@@ -638960,15 +641157,38 @@ ${result.text}`;
|
|
|
638960
641157
|
}
|
|
638961
641158
|
let fullInput = input;
|
|
638962
641159
|
if (isImage && fullInput === input) {
|
|
641160
|
+
const imgPath = resolve46(repoRoot, cleanPath);
|
|
638963
641161
|
const asciiContext = await renderAsciiPreviewForImage(
|
|
638964
|
-
|
|
641162
|
+
imgPath,
|
|
638965
641163
|
cleanPath,
|
|
638966
641164
|
"Image context",
|
|
638967
641165
|
writeContent
|
|
638968
641166
|
);
|
|
638969
|
-
|
|
641167
|
+
let visualIdentityContext = "";
|
|
641168
|
+
try {
|
|
641169
|
+
const ext = extname17(cleanPath).toLowerCase();
|
|
641170
|
+
const mime = ext === ".png" ? "image/png" : ext === ".gif" ? "image/gif" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
641171
|
+
const association = await associateVisualIdentityFromImage({
|
|
641172
|
+
repoRoot,
|
|
641173
|
+
imagePath: imgPath,
|
|
641174
|
+
sourceSurface: "tui",
|
|
641175
|
+
scope: {
|
|
641176
|
+
kind: "terminal",
|
|
641177
|
+
id: process.env["OMNIUS_SESSION_ID"] || "terminal",
|
|
641178
|
+
title: "TUI session"
|
|
641179
|
+
},
|
|
641180
|
+
sender: { id: "local-user", displayName: "User" },
|
|
641181
|
+
message: { timestamp: Date.now(), text: `User provided image file: ${cleanPath}` },
|
|
641182
|
+
sessionId: process.env["OMNIUS_SESSION_ID"] || "terminal",
|
|
641183
|
+
media: { path: imgPath, mediaType: "photo", mimeType: mime }
|
|
641184
|
+
});
|
|
641185
|
+
visualIdentityContext = association.contextBlock;
|
|
641186
|
+
} catch {
|
|
641187
|
+
}
|
|
641188
|
+
const imageContext = [asciiContext, visualIdentityContext].filter(Boolean).join("\n\n");
|
|
641189
|
+
fullInput = imageContext ? `The user has provided an image file: ${cleanPath}.
|
|
638970
641190
|
|
|
638971
|
-
${
|
|
641191
|
+
${imageContext}
|
|
638972
641192
|
|
|
638973
641193
|
Read it with image_read or vision if more detail is needed. Describe what you see and extract any text with OCR if relevant.` : `The user has provided an image file: ${cleanPath}. Read it with image_read and describe what you see. Extract any text with OCR if relevant.`;
|
|
638974
641194
|
}
|
|
@@ -639168,13 +641388,13 @@ NEW TASK: ${fullInput}`;
|
|
|
639168
641388
|
writeContent(() => renderError(errMsg));
|
|
639169
641389
|
if (failureStore) {
|
|
639170
641390
|
try {
|
|
639171
|
-
const { createHash:
|
|
641391
|
+
const { createHash: createHash28 } = await import("node:crypto");
|
|
639172
641392
|
failureStore.insert({
|
|
639173
641393
|
taskId: "",
|
|
639174
641394
|
sessionId: `${Date.now()}`,
|
|
639175
641395
|
repoRoot,
|
|
639176
641396
|
failureType: "runtime-error",
|
|
639177
|
-
fingerprint:
|
|
641397
|
+
fingerprint: createHash28("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
|
|
639178
641398
|
filePath: null,
|
|
639179
641399
|
errorMessage: errMsg.slice(0, 500),
|
|
639180
641400
|
context: null,
|
|
@@ -639922,6 +642142,7 @@ var init_interactive = __esm({
|
|
|
639922
642142
|
init_model_picker();
|
|
639923
642143
|
init_project_context();
|
|
639924
642144
|
init_identity_memory_tool();
|
|
642145
|
+
init_visual_identity_association();
|
|
639925
642146
|
init_dist7();
|
|
639926
642147
|
init_omnius_directory();
|
|
639927
642148
|
init_render();
|