@askexenow/exe-os 0.9.92 → 0.9.94
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/deploy/compose/docker-compose.yml +1 -0
- package/dist/bin/agentic-ontology-backfill.js +65 -8
- package/dist/bin/agentic-reflection-backfill.js +54 -3
- package/dist/bin/agentic-semantic-label.js +54 -3
- package/dist/bin/backfill-conversations.js +69 -9
- package/dist/bin/backfill-responses.js +69 -9
- package/dist/bin/backfill-vectors.js +54 -3
- package/dist/bin/bulk-sync-postgres.js +66 -8
- package/dist/bin/cleanup-stale-review-tasks.js +118 -13
- package/dist/bin/cli.js +1605 -456
- package/dist/bin/customer-readiness.js +51 -0
- package/dist/bin/exe-agent.js +17 -3
- package/dist/bin/exe-assign.js +75 -9
- package/dist/bin/exe-boot.js +111 -12
- package/dist/bin/exe-call.js +17 -3
- package/dist/bin/exe-cloud.js +76 -10
- package/dist/bin/exe-dispatch.js +133 -18
- package/dist/bin/exe-doctor.js +75 -9
- package/dist/bin/exe-export-behaviors.js +75 -9
- package/dist/bin/exe-forget.js +94 -9
- package/dist/bin/exe-gateway.js +132 -18
- package/dist/bin/exe-heartbeat.js +118 -13
- package/dist/bin/exe-kill.js +75 -9
- package/dist/bin/exe-launch-agent.js +75 -9
- package/dist/bin/exe-new-employee.js +18 -4
- package/dist/bin/exe-pending-messages.js +118 -13
- package/dist/bin/exe-pending-notifications.js +118 -13
- package/dist/bin/exe-pending-reviews.js +118 -13
- package/dist/bin/exe-rename.js +75 -9
- package/dist/bin/exe-review.js +75 -9
- package/dist/bin/exe-search.js +100 -9
- package/dist/bin/exe-session-cleanup.js +133 -18
- package/dist/bin/exe-settings.js +1 -0
- package/dist/bin/exe-start-codex.js +65 -8
- package/dist/bin/exe-start-opencode.js +65 -8
- package/dist/bin/exe-status.js +118 -13
- package/dist/bin/exe-support.js +1 -0
- package/dist/bin/exe-team.js +75 -9
- package/dist/bin/git-sweep.js +133 -18
- package/dist/bin/graph-backfill.js +65 -8
- package/dist/bin/graph-export.js +75 -9
- package/dist/bin/intercom-check.js +133 -18
- package/dist/bin/scan-tasks.js +133 -18
- package/dist/bin/setup.js +55 -4
- package/dist/bin/shard-migrate.js +65 -8
- package/dist/bin/stack-update.js +57 -1
- package/dist/bin/update.js +1 -1
- package/dist/gateway/index.js +133 -18
- package/dist/hooks/bug-report-worker.js +133 -18
- package/dist/hooks/codex-stop-task-finalizer.js +123 -14
- package/dist/hooks/commit-complete.js +133 -18
- package/dist/hooks/error-recall.js +100 -9
- package/dist/hooks/ingest.js +75 -9
- package/dist/hooks/instructions-loaded.js +75 -9
- package/dist/hooks/notification.js +75 -9
- package/dist/hooks/post-compact.js +310 -50
- package/dist/hooks/post-tool-combined.js +433 -13
- package/dist/hooks/pre-compact.js +133 -18
- package/dist/hooks/pre-tool-use.js +118 -13
- package/dist/hooks/prompt-submit.js +191 -19
- package/dist/hooks/session-end.js +133 -18
- package/dist/hooks/session-start.js +143 -13
- package/dist/hooks/stop.js +118 -13
- package/dist/hooks/subagent-stop.js +118 -13
- package/dist/hooks/summary-worker.js +96 -7
- package/dist/index.js +133 -18
- package/dist/lib/cloud-sync.js +38 -0
- package/dist/lib/consolidation.js +3 -1
- package/dist/lib/database.js +37 -0
- package/dist/lib/db.js +37 -0
- package/dist/lib/device-registry.js +37 -0
- package/dist/lib/employee-templates.js +17 -3
- package/dist/lib/exe-daemon.js +913 -42
- package/dist/lib/hybrid-search.js +100 -9
- package/dist/lib/license.js +1 -1
- package/dist/lib/messaging.js +40 -4
- package/dist/lib/schedules.js +54 -3
- package/dist/lib/store.js +75 -9
- package/dist/lib/tasks.js +58 -9
- package/dist/lib/tmux-routing.js +58 -9
- package/dist/mcp/server.js +875 -42
- package/dist/mcp/tools/create-task.js +67 -12
- package/dist/mcp/tools/list-tasks.js +46 -5
- package/dist/mcp/tools/send-message.js +40 -4
- package/dist/mcp/tools/update-task.js +58 -9
- package/dist/runtime/index.js +133 -18
- package/dist/tui/App.js +132 -18
- package/package.json +1 -1
|
@@ -3062,6 +3062,20 @@ async function ensureSchema() {
|
|
|
3062
3062
|
});
|
|
3063
3063
|
} catch {
|
|
3064
3064
|
}
|
|
3065
|
+
try {
|
|
3066
|
+
await client.execute({
|
|
3067
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
3068
|
+
args: []
|
|
3069
|
+
});
|
|
3070
|
+
} catch {
|
|
3071
|
+
}
|
|
3072
|
+
try {
|
|
3073
|
+
await client.execute({
|
|
3074
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
3075
|
+
args: []
|
|
3076
|
+
});
|
|
3077
|
+
} catch {
|
|
3078
|
+
}
|
|
3065
3079
|
await client.executeMultiple(`
|
|
3066
3080
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
3067
3081
|
content_text,
|
|
@@ -3313,6 +3327,22 @@ async function ensureSchema() {
|
|
|
3313
3327
|
);
|
|
3314
3328
|
} catch {
|
|
3315
3329
|
}
|
|
3330
|
+
for (const col of [
|
|
3331
|
+
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
3332
|
+
"ALTER TABLE memories ADD COLUMN invalid_at TEXT"
|
|
3333
|
+
]) {
|
|
3334
|
+
try {
|
|
3335
|
+
await client.execute(col);
|
|
3336
|
+
} catch {
|
|
3337
|
+
}
|
|
3338
|
+
}
|
|
3339
|
+
try {
|
|
3340
|
+
await client.execute({
|
|
3341
|
+
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3342
|
+
args: []
|
|
3343
|
+
});
|
|
3344
|
+
} catch {
|
|
3345
|
+
}
|
|
3316
3346
|
try {
|
|
3317
3347
|
await client.execute({
|
|
3318
3348
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
@@ -3355,6 +3385,13 @@ async function ensureSchema() {
|
|
|
3355
3385
|
} catch {
|
|
3356
3386
|
}
|
|
3357
3387
|
}
|
|
3388
|
+
try {
|
|
3389
|
+
await client.execute({
|
|
3390
|
+
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3391
|
+
args: []
|
|
3392
|
+
});
|
|
3393
|
+
} catch {
|
|
3394
|
+
}
|
|
3358
3395
|
try {
|
|
3359
3396
|
await client.execute({
|
|
3360
3397
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
@@ -3415,7 +3452,7 @@ import { pathToFileURL as pathToFileURL2 } from "url";
|
|
|
3415
3452
|
import os7 from "os";
|
|
3416
3453
|
import path10 from "path";
|
|
3417
3454
|
import { jwtVerify, importSPKI } from "jose";
|
|
3418
|
-
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
|
|
3455
|
+
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE;
|
|
3419
3456
|
var init_license = __esm({
|
|
3420
3457
|
"src/lib/license.ts"() {
|
|
3421
3458
|
"use strict";
|
|
@@ -3423,6 +3460,7 @@ var init_license = __esm({
|
|
|
3423
3460
|
LICENSE_PATH = path10.join(EXE_AI_DIR, "license.key");
|
|
3424
3461
|
CACHE_PATH = path10.join(EXE_AI_DIR, "license-cache.json");
|
|
3425
3462
|
DEVICE_ID_PATH = path10.join(EXE_AI_DIR, "device-id");
|
|
3463
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
3426
3464
|
}
|
|
3427
3465
|
});
|
|
3428
3466
|
|
|
@@ -3466,6 +3504,9 @@ import { fileURLToPath as fileURLToPath2 } from "url";
|
|
|
3466
3504
|
function getMySession() {
|
|
3467
3505
|
return getTransport().getMySession();
|
|
3468
3506
|
}
|
|
3507
|
+
function isRootSession(name) {
|
|
3508
|
+
return name.length > 0 && !name.includes("-");
|
|
3509
|
+
}
|
|
3469
3510
|
function extractRootExe(name) {
|
|
3470
3511
|
if (!name) return null;
|
|
3471
3512
|
if (!name.includes("-")) return name;
|
|
@@ -3484,6 +3525,7 @@ function resolveExeSession() {
|
|
|
3484
3525
|
const mySession = getMySession();
|
|
3485
3526
|
if (!mySession) return null;
|
|
3486
3527
|
const fromSessionName = extractRootExe(mySession);
|
|
3528
|
+
let candidate = null;
|
|
3487
3529
|
try {
|
|
3488
3530
|
const key = getSessionKey();
|
|
3489
3531
|
const parentExe = getParentExe(key);
|
|
@@ -3494,13 +3536,47 @@ function resolveExeSession() {
|
|
|
3494
3536
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
3495
3537
|
`
|
|
3496
3538
|
);
|
|
3497
|
-
|
|
3539
|
+
candidate = fromSessionName;
|
|
3540
|
+
} else {
|
|
3541
|
+
candidate = fromCache;
|
|
3498
3542
|
}
|
|
3499
|
-
return fromCache;
|
|
3500
3543
|
}
|
|
3501
3544
|
} catch {
|
|
3502
3545
|
}
|
|
3503
|
-
|
|
3546
|
+
if (!candidate) {
|
|
3547
|
+
candidate = fromSessionName ?? mySession;
|
|
3548
|
+
}
|
|
3549
|
+
if (candidate && isRootSession(candidate)) {
|
|
3550
|
+
try {
|
|
3551
|
+
const transport = getTransport();
|
|
3552
|
+
const liveSessions = transport.listSessions();
|
|
3553
|
+
if (!liveSessions.includes(candidate)) {
|
|
3554
|
+
const liveRoots = liveSessions.filter((s) => isRootSession(s));
|
|
3555
|
+
if (liveRoots.length === 1) {
|
|
3556
|
+
process.stderr.write(
|
|
3557
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. Using live coordinator "${liveRoots[0]}".
|
|
3558
|
+
`
|
|
3559
|
+
);
|
|
3560
|
+
return liveRoots[0];
|
|
3561
|
+
} else if (liveRoots.length > 1) {
|
|
3562
|
+
const base = candidate.replace(/\d+$/, "");
|
|
3563
|
+
const match = liveRoots.find((s) => s.startsWith(base));
|
|
3564
|
+
const chosen = match ?? liveRoots[0];
|
|
3565
|
+
process.stderr.write(
|
|
3566
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. ${liveRoots.length} live roots found, using "${chosen}".
|
|
3567
|
+
`
|
|
3568
|
+
);
|
|
3569
|
+
return chosen;
|
|
3570
|
+
}
|
|
3571
|
+
process.stderr.write(
|
|
3572
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead and no live coordinator found.
|
|
3573
|
+
`
|
|
3574
|
+
);
|
|
3575
|
+
}
|
|
3576
|
+
} catch {
|
|
3577
|
+
}
|
|
3578
|
+
}
|
|
3579
|
+
return candidate;
|
|
3504
3580
|
}
|
|
3505
3581
|
var SPAWN_LOCK_DIR, SESSION_CACHE, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS;
|
|
3506
3582
|
var init_tmux_routing = __esm({
|
|
@@ -3550,17 +3626,157 @@ var init_task_scope = __esm({
|
|
|
3550
3626
|
}
|
|
3551
3627
|
});
|
|
3552
3628
|
|
|
3629
|
+
// src/lib/identity.ts
|
|
3630
|
+
var identity_exports = {};
|
|
3631
|
+
__export(identity_exports, {
|
|
3632
|
+
getIdentity: () => getIdentity,
|
|
3633
|
+
getIdentityInjection: () => getIdentityInjection,
|
|
3634
|
+
identityPath: () => identityPath,
|
|
3635
|
+
listIdentities: () => listIdentities,
|
|
3636
|
+
updateIdentity: () => updateIdentity
|
|
3637
|
+
});
|
|
3638
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync7, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "fs";
|
|
3639
|
+
import { readdirSync as readdirSync3 } from "fs";
|
|
3640
|
+
import path14 from "path";
|
|
3641
|
+
import { createHash } from "crypto";
|
|
3642
|
+
function ensureDir() {
|
|
3643
|
+
if (!existsSync12(IDENTITY_DIR2)) {
|
|
3644
|
+
mkdirSync7(IDENTITY_DIR2, { recursive: true });
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3647
|
+
function identityPath(agentId) {
|
|
3648
|
+
return path14.join(IDENTITY_DIR2, `${agentId}.md`);
|
|
3649
|
+
}
|
|
3650
|
+
function sanitizeIdentityBody(body) {
|
|
3651
|
+
return body.replace(/<!--[\s\S]*?-->/g, "").trim();
|
|
3652
|
+
}
|
|
3653
|
+
function parseFrontmatter(raw) {
|
|
3654
|
+
const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
3655
|
+
if (!match) {
|
|
3656
|
+
return {
|
|
3657
|
+
frontmatter: {
|
|
3658
|
+
role: "unknown",
|
|
3659
|
+
title: "Unknown",
|
|
3660
|
+
agent_id: "unknown",
|
|
3661
|
+
org_level: "specialist",
|
|
3662
|
+
created_by: "system",
|
|
3663
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
3664
|
+
},
|
|
3665
|
+
body: sanitizeIdentityBody(raw)
|
|
3666
|
+
};
|
|
3667
|
+
}
|
|
3668
|
+
const yamlStr = match[1];
|
|
3669
|
+
const body = sanitizeIdentityBody(match[2]);
|
|
3670
|
+
const fm = {};
|
|
3671
|
+
for (const line of yamlStr.split("\n")) {
|
|
3672
|
+
const kv = line.match(/^(\w+):\s*(.+)$/);
|
|
3673
|
+
if (kv) fm[kv[1]] = kv[2].trim();
|
|
3674
|
+
}
|
|
3675
|
+
return {
|
|
3676
|
+
frontmatter: {
|
|
3677
|
+
role: fm.role ?? "unknown",
|
|
3678
|
+
title: fm.title ?? "Unknown",
|
|
3679
|
+
agent_id: fm.agent_id ?? "unknown",
|
|
3680
|
+
org_level: fm.org_level ?? "specialist",
|
|
3681
|
+
created_by: fm.created_by ?? "system",
|
|
3682
|
+
updated_at: fm.updated_at ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
3683
|
+
},
|
|
3684
|
+
body
|
|
3685
|
+
};
|
|
3686
|
+
}
|
|
3687
|
+
function contentHash(content) {
|
|
3688
|
+
return createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
3689
|
+
}
|
|
3690
|
+
function getIdentity(agentId) {
|
|
3691
|
+
const filePath = identityPath(agentId);
|
|
3692
|
+
if (!existsSync12(filePath)) return null;
|
|
3693
|
+
const raw = readFileSync11(filePath, "utf-8");
|
|
3694
|
+
const { frontmatter, body } = parseFrontmatter(raw);
|
|
3695
|
+
return {
|
|
3696
|
+
agentId,
|
|
3697
|
+
frontmatter,
|
|
3698
|
+
body,
|
|
3699
|
+
raw,
|
|
3700
|
+
contentHash: contentHash(raw)
|
|
3701
|
+
};
|
|
3702
|
+
}
|
|
3703
|
+
async function updateIdentity(agentId, content, updatedBy) {
|
|
3704
|
+
ensureDir();
|
|
3705
|
+
const filePath = identityPath(agentId);
|
|
3706
|
+
const hash = contentHash(content);
|
|
3707
|
+
writeFileSync8(filePath, content, "utf-8");
|
|
3708
|
+
try {
|
|
3709
|
+
const client = getClient();
|
|
3710
|
+
await client.execute({
|
|
3711
|
+
sql: `INSERT INTO identity (agent_id, content_hash, updated_at, updated_by)
|
|
3712
|
+
VALUES (?, ?, ?, ?)
|
|
3713
|
+
ON CONFLICT(agent_id) DO UPDATE SET
|
|
3714
|
+
content_hash = excluded.content_hash,
|
|
3715
|
+
updated_at = excluded.updated_at,
|
|
3716
|
+
updated_by = excluded.updated_by`,
|
|
3717
|
+
args: [agentId, hash, (/* @__PURE__ */ new Date()).toISOString(), updatedBy]
|
|
3718
|
+
});
|
|
3719
|
+
} catch {
|
|
3720
|
+
}
|
|
3721
|
+
}
|
|
3722
|
+
function listIdentities() {
|
|
3723
|
+
ensureDir();
|
|
3724
|
+
const files = readdirSync3(IDENTITY_DIR2).filter((f) => f.endsWith(".md"));
|
|
3725
|
+
const results = [];
|
|
3726
|
+
for (const file of files) {
|
|
3727
|
+
const agentId = file.replace(".md", "");
|
|
3728
|
+
const identity = getIdentity(agentId);
|
|
3729
|
+
if (!identity) continue;
|
|
3730
|
+
const lines = identity.body.split("\n").filter((l) => l.trim() && !l.startsWith("#"));
|
|
3731
|
+
const summary = lines[0]?.trim().slice(0, 120) ?? identity.frontmatter.title;
|
|
3732
|
+
results.push({
|
|
3733
|
+
agentId,
|
|
3734
|
+
// User-facing/team-facing title only. `frontmatter.role` is internal
|
|
3735
|
+
// routing metadata and must not leak as an external title.
|
|
3736
|
+
title: identity.frontmatter.title,
|
|
3737
|
+
summary
|
|
3738
|
+
});
|
|
3739
|
+
}
|
|
3740
|
+
return results;
|
|
3741
|
+
}
|
|
3742
|
+
function getIdentityInjection(agentId) {
|
|
3743
|
+
const own = getIdentity(agentId);
|
|
3744
|
+
const all = listIdentities();
|
|
3745
|
+
const parts = [];
|
|
3746
|
+
if (own) {
|
|
3747
|
+
parts.push(`## Your Identity (exe.md)
|
|
3748
|
+
These define WHO YOU ARE. Non-negotiable. Permanent.
|
|
3749
|
+
|
|
3750
|
+
${own.body}`);
|
|
3751
|
+
}
|
|
3752
|
+
const teamLines = all.filter((a) => a.agentId !== agentId).map((a) => `- ${a.agentId} (${a.title}): ${a.summary}`);
|
|
3753
|
+
if (teamLines.length > 0) {
|
|
3754
|
+
parts.push(`## Team Identities
|
|
3755
|
+
${teamLines.join("\n")}`);
|
|
3756
|
+
}
|
|
3757
|
+
return parts.join("\n\n");
|
|
3758
|
+
}
|
|
3759
|
+
var IDENTITY_DIR2;
|
|
3760
|
+
var init_identity = __esm({
|
|
3761
|
+
"src/lib/identity.ts"() {
|
|
3762
|
+
"use strict";
|
|
3763
|
+
init_config();
|
|
3764
|
+
init_database();
|
|
3765
|
+
IDENTITY_DIR2 = path14.join(EXE_AI_DIR, "identity");
|
|
3766
|
+
}
|
|
3767
|
+
});
|
|
3768
|
+
|
|
3553
3769
|
// src/lib/keychain.ts
|
|
3554
3770
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
3555
|
-
import { existsSync as
|
|
3771
|
+
import { existsSync as existsSync13, statSync as statSync2 } from "fs";
|
|
3556
3772
|
import { execSync as execSync6 } from "child_process";
|
|
3557
|
-
import
|
|
3773
|
+
import path15 from "path";
|
|
3558
3774
|
import os10 from "os";
|
|
3559
3775
|
function getKeyDir() {
|
|
3560
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ??
|
|
3776
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path15.join(os10.homedir(), ".exe-os");
|
|
3561
3777
|
}
|
|
3562
3778
|
function getKeyPath() {
|
|
3563
|
-
return
|
|
3779
|
+
return path15.join(getKeyDir(), "master.key");
|
|
3564
3780
|
}
|
|
3565
3781
|
function nativeKeychainAllowed() {
|
|
3566
3782
|
return process.env.EXE_OS_DISABLE_NATIVE_KEYCHAIN !== "1";
|
|
@@ -3591,7 +3807,7 @@ function isRootOnlyTrustedServerKeyFile(keyPath) {
|
|
|
3591
3807
|
if (!st.isFile() || (st.mode & 63) !== 0) return false;
|
|
3592
3808
|
if (uid === 0) return true;
|
|
3593
3809
|
const exeOsDir = process.env.EXE_OS_DIR;
|
|
3594
|
-
return Boolean(exeOsDir &&
|
|
3810
|
+
return Boolean(exeOsDir && path15.resolve(keyPath).startsWith(path15.resolve(exeOsDir) + path15.sep));
|
|
3595
3811
|
} catch {
|
|
3596
3812
|
return false;
|
|
3597
3813
|
}
|
|
@@ -3703,8 +3919,8 @@ function deriveMachineKey() {
|
|
|
3703
3919
|
}
|
|
3704
3920
|
function readMachineId() {
|
|
3705
3921
|
try {
|
|
3706
|
-
const { readFileSync:
|
|
3707
|
-
return
|
|
3922
|
+
const { readFileSync: readFileSync12 } = __require("fs");
|
|
3923
|
+
return readFileSync12("/etc/machine-id", "utf-8").trim();
|
|
3708
3924
|
} catch {
|
|
3709
3925
|
return "";
|
|
3710
3926
|
}
|
|
@@ -3788,7 +4004,7 @@ async function getMasterKey() {
|
|
|
3788
4004
|
}
|
|
3789
4005
|
}
|
|
3790
4006
|
const keyPath = getKeyPath();
|
|
3791
|
-
if (!
|
|
4007
|
+
if (!existsSync13(keyPath)) {
|
|
3792
4008
|
process.stderr.write(
|
|
3793
4009
|
`[keychain] Key not found at ${keyPath} (HOME=${os10.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
|
|
3794
4010
|
`
|
|
@@ -3914,7 +4130,7 @@ var init_state_bus = __esm({
|
|
|
3914
4130
|
});
|
|
3915
4131
|
|
|
3916
4132
|
// src/lib/memory-write-governor.ts
|
|
3917
|
-
import { createHash } from "crypto";
|
|
4133
|
+
import { createHash as createHash2 } from "crypto";
|
|
3918
4134
|
function normalizeMemoryText(text) {
|
|
3919
4135
|
return text.replace(/\r\n/g, "\n").replace(/[ \t]+$/gm, "").replace(/\n{4,}/g, "\n\n\n").trim();
|
|
3920
4136
|
}
|
|
@@ -3949,7 +4165,7 @@ function shouldSkipEmbedding(input2) {
|
|
|
3949
4165
|
return false;
|
|
3950
4166
|
}
|
|
3951
4167
|
function hashMemoryContent(text) {
|
|
3952
|
-
return
|
|
4168
|
+
return createHash2("sha256").update(normalizeMemoryText(text)).digest("hex");
|
|
3953
4169
|
}
|
|
3954
4170
|
function scopedDedupArgs(input2) {
|
|
3955
4171
|
return [input2.contentHash, input2.agentId, input2.projectName, input2.memoryType];
|
|
@@ -4021,10 +4237,10 @@ async function runPostWriteMemoryHygiene(memoryId) {
|
|
|
4021
4237
|
const row = current.rows[0];
|
|
4022
4238
|
if (!row) return;
|
|
4023
4239
|
const memoryType = String(row.memory_type ?? "raw");
|
|
4024
|
-
const
|
|
4240
|
+
const contentHash2 = row.content_hash ? String(row.content_hash) : null;
|
|
4025
4241
|
const agentId = String(row.agent_id);
|
|
4026
4242
|
const projectName = String(row.project_name);
|
|
4027
|
-
if (
|
|
4243
|
+
if (contentHash2) {
|
|
4028
4244
|
await client.execute({
|
|
4029
4245
|
sql: `UPDATE memories
|
|
4030
4246
|
SET status = 'deleted',
|
|
@@ -4035,7 +4251,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
|
|
|
4035
4251
|
AND project_name = ?
|
|
4036
4252
|
AND COALESCE(memory_type, 'raw') = ?
|
|
4037
4253
|
AND COALESCE(status, 'active') = 'active'`,
|
|
4038
|
-
args: [memoryId,
|
|
4254
|
+
args: [memoryId, contentHash2, agentId, projectName, memoryType]
|
|
4039
4255
|
});
|
|
4040
4256
|
}
|
|
4041
4257
|
const supersedesId = row.supersedes_id ? String(row.supersedes_id) : null;
|
|
@@ -4122,13 +4338,13 @@ __export(shard_manager_exports, {
|
|
|
4122
4338
|
listShards: () => listShards,
|
|
4123
4339
|
shardExists: () => shardExists
|
|
4124
4340
|
});
|
|
4125
|
-
import
|
|
4126
|
-
import { existsSync as
|
|
4341
|
+
import path16 from "path";
|
|
4342
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync8, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync3 } from "fs";
|
|
4127
4343
|
import { createClient as createClient2 } from "@libsql/client";
|
|
4128
4344
|
function initShardManager(encryptionKey) {
|
|
4129
4345
|
_encryptionKey = encryptionKey;
|
|
4130
|
-
if (!
|
|
4131
|
-
|
|
4346
|
+
if (!existsSync14(SHARDS_DIR)) {
|
|
4347
|
+
mkdirSync8(SHARDS_DIR, { recursive: true });
|
|
4132
4348
|
}
|
|
4133
4349
|
_shardingEnabled = true;
|
|
4134
4350
|
if (_evictionTimer) clearInterval(_evictionTimer);
|
|
@@ -4157,7 +4373,7 @@ function getShardClient(projectName) {
|
|
|
4157
4373
|
while (_shards.size >= MAX_OPEN_SHARDS) {
|
|
4158
4374
|
evictLRU();
|
|
4159
4375
|
}
|
|
4160
|
-
const dbPath =
|
|
4376
|
+
const dbPath = path16.join(SHARDS_DIR, `${safeName}.db`);
|
|
4161
4377
|
const client = createClient2({
|
|
4162
4378
|
url: `file:${dbPath}`,
|
|
4163
4379
|
encryptionKey: _encryptionKey
|
|
@@ -4168,14 +4384,14 @@ function getShardClient(projectName) {
|
|
|
4168
4384
|
}
|
|
4169
4385
|
function shardExists(projectName) {
|
|
4170
4386
|
const safeName = safeShardName(projectName);
|
|
4171
|
-
return
|
|
4387
|
+
return existsSync14(path16.join(SHARDS_DIR, `${safeName}.db`));
|
|
4172
4388
|
}
|
|
4173
4389
|
function safeShardName(projectName) {
|
|
4174
4390
|
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
4175
4391
|
}
|
|
4176
4392
|
function listShards() {
|
|
4177
|
-
if (!
|
|
4178
|
-
return
|
|
4393
|
+
if (!existsSync14(SHARDS_DIR)) return [];
|
|
4394
|
+
return readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
4179
4395
|
}
|
|
4180
4396
|
async function auditShardHealth(options = {}) {
|
|
4181
4397
|
if (!_encryptionKey) {
|
|
@@ -4186,7 +4402,7 @@ async function auditShardHealth(options = {}) {
|
|
|
4186
4402
|
const names = listShards();
|
|
4187
4403
|
const shards = [];
|
|
4188
4404
|
for (const name of names) {
|
|
4189
|
-
const dbPath =
|
|
4405
|
+
const dbPath = path16.join(SHARDS_DIR, `${name}.db`);
|
|
4190
4406
|
const stat = statSync3(dbPath);
|
|
4191
4407
|
const item = {
|
|
4192
4408
|
name,
|
|
@@ -4221,7 +4437,7 @@ async function auditShardHealth(options = {}) {
|
|
|
4221
4437
|
_shards.delete(name);
|
|
4222
4438
|
_shardLastAccess.delete(name);
|
|
4223
4439
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
4224
|
-
const archivedPath =
|
|
4440
|
+
const archivedPath = path16.join(SHARDS_DIR, `${name}.db.broken-${stamp}`);
|
|
4225
4441
|
renameSync4(dbPath, archivedPath);
|
|
4226
4442
|
item.archivedPath = archivedPath;
|
|
4227
4443
|
}
|
|
@@ -4438,11 +4654,11 @@ async function getReadyShardClient(projectName) {
|
|
|
4438
4654
|
client.close();
|
|
4439
4655
|
_shards.delete(safeName);
|
|
4440
4656
|
_shardLastAccess.delete(safeName);
|
|
4441
|
-
const dbPath =
|
|
4442
|
-
if (
|
|
4657
|
+
const dbPath = path16.join(SHARDS_DIR, `${safeName}.db`);
|
|
4658
|
+
if (existsSync14(dbPath)) {
|
|
4443
4659
|
const stat = statSync3(dbPath);
|
|
4444
4660
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
4445
|
-
const archivedPath =
|
|
4661
|
+
const archivedPath = path16.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
4446
4662
|
renameSync4(dbPath, archivedPath);
|
|
4447
4663
|
process.stderr.write(
|
|
4448
4664
|
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
@@ -4510,7 +4726,7 @@ var init_shard_manager = __esm({
|
|
|
4510
4726
|
"src/lib/shard-manager.ts"() {
|
|
4511
4727
|
"use strict";
|
|
4512
4728
|
init_config();
|
|
4513
|
-
SHARDS_DIR =
|
|
4729
|
+
SHARDS_DIR = path16.join(EXE_AI_DIR, "shards");
|
|
4514
4730
|
SHARD_IDLE_MS = 5 * 60 * 1e3;
|
|
4515
4731
|
MAX_OPEN_SHARDS = 10;
|
|
4516
4732
|
EVICTION_INTERVAL_MS = 60 * 1e3;
|
|
@@ -4636,6 +4852,20 @@ var init_platform_procedures = __esm({
|
|
|
4636
4852
|
priority: "p1",
|
|
4637
4853
|
content: "Once per session (COO boot only, never repeat), call list_my_feature_requests to check if any previously filed feature requests have been shipped by AskExe. If any request has status 'shipped' with a shipped_version, surface it to the founder immediately: '\u{1F680} N feature(s) shipped \u2014 run exe-os update to get version X.Y.Z'. This is a one-time check at boot, not a recurring poll. If no requests exist or none are shipped, skip silently. If the MCP tool is unavailable or the network call fails, skip silently \u2014 this is informational, not blocking."
|
|
4638
4854
|
},
|
|
4855
|
+
// --- Tool guidance ---
|
|
4856
|
+
{
|
|
4857
|
+
title: "How to use company_actions \u2014 execute business actions through gateway connectors",
|
|
4858
|
+
domain: "tools",
|
|
4859
|
+
priority: "p2",
|
|
4860
|
+
content: "The company_actions tool executes business actions through gateway connectors (e.g. send WhatsApp, trigger workflows, update CRM). It routes through the exe-gateway on the VPS. Actions are defined by the customer's gateway configuration \u2014 each connector (WhatsApp, Shopify, email, etc.) exposes specific actions. Use query_company_brain to find available data first, then company_actions to act on it. Requires gateway auth token. Read-only founders should NOT use this \u2014 it mutates external state."
|
|
4861
|
+
},
|
|
4862
|
+
// --- Release awareness ---
|
|
4863
|
+
{
|
|
4864
|
+
title: "What's New check \u2014 surface new features after update",
|
|
4865
|
+
domain: "support",
|
|
4866
|
+
priority: "p1",
|
|
4867
|
+
content: "Once per session (COO boot only, never repeat), check if the installed exe-os version is newer than the last session. If it is, read the bundled release-notes.json (at the package root) and surface a brief summary to the founder: 'Updated to exe-os vX.Y.Z \u2014 N new features, M fixes.' List the top 3 features by name. This helps the founder know what they got from the update. If release-notes.json doesn't exist or the version hasn't changed, skip silently. Never repeat this check in the same session."
|
|
4868
|
+
},
|
|
4639
4869
|
// --- Platform vs Customer ownership ---
|
|
4640
4870
|
{
|
|
4641
4871
|
title: "What the platform provides vs what you customize",
|
|
@@ -4724,13 +4954,13 @@ var init_platform_procedures = __esm({
|
|
|
4724
4954
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
4725
4955
|
domain: "tool-use",
|
|
4726
4956
|
priority: "p1",
|
|
4727
|
-
content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
|
|
4957
|
+
content: `memory(action="recall") / recall_my_memory: search your own memories (semantic + FTS). Supports as_of param for bi-temporal queries (what did I know at time X?), kind param to filter by memory type (decision, procedure, observation, raw, conversation, behavior). memory(action="ask_team") / ask_team_memory: search a colleague's memories by agent name. memory(action="store") / store_memory: persist a memory. Supports kind param and procedure_for domain tag for procedure-type memories. memory(action="commit") / commit_memory: high-importance memory that survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal memory window. Requires session_id + target_timestamp. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. memory(action="supersede") / supersede: replace an old memory with a new version (old_id + new text). decision(action="store") / store_decision: record an architectural decision (domain, decision, rationale). decision(action="get") / get_decision: retrieve a past decision by domain or query.`
|
|
4728
4958
|
},
|
|
4729
4959
|
{
|
|
4730
4960
|
title: "MCP tools \u2014 task orchestration",
|
|
4731
4961
|
domain: "tool-use",
|
|
4732
4962
|
priority: "p1",
|
|
4733
|
-
content:
|
|
4963
|
+
content: `task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. Supports spawn_runtime and spawn_model params to override the agent's default runtime/model for a specific task. task(action="list") / list_tasks: query tasks by status, assignee, project. task(action="get") / get_task: fetch full task details by task_id. task(action="update") / update_task: change status (in_progress, done, blocked, cancelled) + result summary. task(action="close") / close_task: finalize a reviewed task (COO only). task(action="checkpoint") / checkpoint_task: save progress state for crash recovery. task(action="resume") / resume_employee: re-spawn an employee session for an existing task.`
|
|
4734
4964
|
},
|
|
4735
4965
|
{
|
|
4736
4966
|
title: "MCP tools \u2014 knowledge graph (GraphRAG)",
|
|
@@ -4760,7 +4990,7 @@ var init_platform_procedures = __esm({
|
|
|
4760
4990
|
title: "MCP tools \u2014 admin, config, and operations",
|
|
4761
4991
|
domain: "tool-use",
|
|
4762
4992
|
priority: "p1",
|
|
4763
|
-
content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. mcp_ping(): daemon health + license status + tool usage stats.'
|
|
4993
|
+
content: 'config(action="list_employees"): view roster. config(action="agent_spend"): token usage per agent. config(action="daemon_health"): check exed status. config(action="license_status"): check license. config(action="cloud_sync"): force sync. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="company_procedure", subaction="store|list|deactivate"): manage company procedures. config(action="global_procedure"): list all procedures (platform + company). config(action="create_trigger|list_triggers"): scheduled agent jobs. config(action="export_orchestration|import_orchestration"): portable org state. diagnostics(action="healthcheck|doctor|status_brief|check_update|cloud_status"): system diagnostics. diagnostics(action="tool_search"): semantic tool discovery \u2014 find relevant MCP tools by natural language query. Returns top-K tools ranked by relevance. diagnostics(action="drift"): identity drift detection \u2014 score how far an agent has drifted from its role identity. Returns drift score + recommendations. mcp_ping(): daemon health + license status + tool usage stats.'
|
|
4764
4994
|
}
|
|
4765
4995
|
];
|
|
4766
4996
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -4847,9 +5077,9 @@ __export(memory_cards_exports, {
|
|
|
4847
5077
|
insertMemoryCardsForBatch: () => insertMemoryCardsForBatch,
|
|
4848
5078
|
searchMemoryCards: () => searchMemoryCards
|
|
4849
5079
|
});
|
|
4850
|
-
import { createHash as
|
|
5080
|
+
import { createHash as createHash3 } from "crypto";
|
|
4851
5081
|
function stableId(memoryId, type, content) {
|
|
4852
|
-
return
|
|
5082
|
+
return createHash3("sha256").update(`${memoryId}:${type}:${content}`).digest("hex").slice(0, 32);
|
|
4853
5083
|
}
|
|
4854
5084
|
function cleanText(text) {
|
|
4855
5085
|
return text.replace(/```[\s\S]*?```/g, " ").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -5012,9 +5242,9 @@ __export(agentic_ontology_exports, {
|
|
|
5012
5242
|
ontologyPayload: () => ontologyPayload,
|
|
5013
5243
|
stableId: () => stableId2
|
|
5014
5244
|
});
|
|
5015
|
-
import { createHash as
|
|
5245
|
+
import { createHash as createHash4 } from "crypto";
|
|
5016
5246
|
function stableId2(...parts) {
|
|
5017
|
-
return
|
|
5247
|
+
return createHash4("sha256").update(parts.map((p) => String(p ?? "")).join("::")).digest("hex").slice(0, 32);
|
|
5018
5248
|
}
|
|
5019
5249
|
function clean(text, max = 240) {
|
|
5020
5250
|
return text.replace(/\u0000/g, "").replace(/```[\s\S]*?```/g, " ").replace(/\s+/g, " ").trim().slice(0, max);
|
|
@@ -5400,16 +5630,16 @@ async function writeMemory(record) {
|
|
|
5400
5630
|
const governed = governMemoryRecord(record);
|
|
5401
5631
|
if (governed.shouldDrop) return;
|
|
5402
5632
|
record = governed.record;
|
|
5403
|
-
const
|
|
5633
|
+
const contentHash2 = governed.contentHash;
|
|
5404
5634
|
const memoryType = record.memory_type ?? "raw";
|
|
5405
5635
|
if (_pendingRecords.some(
|
|
5406
|
-
(r) => r.content_hash ===
|
|
5636
|
+
(r) => r.content_hash === contentHash2 && r.agent_id === record.agent_id && r.project_name === record.project_name && (r.memory_type ?? "raw") === memoryType
|
|
5407
5637
|
)) {
|
|
5408
5638
|
return;
|
|
5409
5639
|
}
|
|
5410
5640
|
try {
|
|
5411
5641
|
const existing = await findScopedDuplicate({
|
|
5412
|
-
contentHash,
|
|
5642
|
+
contentHash: contentHash2,
|
|
5413
5643
|
agentId: record.agent_id,
|
|
5414
5644
|
projectName: record.project_name,
|
|
5415
5645
|
memoryType
|
|
@@ -5444,10 +5674,12 @@ async function writeMemory(record) {
|
|
|
5444
5674
|
source_type: record.source_type ?? null,
|
|
5445
5675
|
tier: record.tier ?? classifyTier(record),
|
|
5446
5676
|
supersedes_id: record.supersedes_id ?? null,
|
|
5677
|
+
valid_from: record.valid_from ?? record.timestamp,
|
|
5678
|
+
invalid_at: record.invalid_at ?? null,
|
|
5447
5679
|
draft: record.draft ? 1 : 0,
|
|
5448
5680
|
memory_type: memoryType,
|
|
5449
5681
|
trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
|
|
5450
|
-
content_hash:
|
|
5682
|
+
content_hash: contentHash2,
|
|
5451
5683
|
intent: record.intent ?? null,
|
|
5452
5684
|
outcome: record.outcome ?? null,
|
|
5453
5685
|
domain: record.domain ?? inferDomain(record),
|
|
@@ -5462,7 +5694,8 @@ async function writeMemory(record) {
|
|
|
5462
5694
|
token_cost: record.token_cost ?? null,
|
|
5463
5695
|
audience: record.audience ?? null,
|
|
5464
5696
|
language_type: record.language_type ?? inferLanguageType(record),
|
|
5465
|
-
parent_memory_id: record.parent_memory_id ?? null
|
|
5697
|
+
parent_memory_id: record.parent_memory_id ?? null,
|
|
5698
|
+
procedure_for: record.procedure_for ?? null
|
|
5466
5699
|
};
|
|
5467
5700
|
_pendingRecords.push(dbRow);
|
|
5468
5701
|
orgBus.emit({
|
|
@@ -5517,10 +5750,12 @@ async function flushBatch() {
|
|
|
5517
5750
|
const sourceType = row.source_type ?? null;
|
|
5518
5751
|
const tier = row.tier ?? 3;
|
|
5519
5752
|
const supersedesId = row.supersedes_id ?? null;
|
|
5753
|
+
const validFrom = row.valid_from ?? row.timestamp;
|
|
5754
|
+
const invalidAt = row.invalid_at ?? null;
|
|
5520
5755
|
const draft = row.draft ? 1 : 0;
|
|
5521
5756
|
const memoryType = row.memory_type ?? "raw";
|
|
5522
5757
|
const trajectory = row.trajectory ?? null;
|
|
5523
|
-
const
|
|
5758
|
+
const contentHash2 = row.content_hash ?? null;
|
|
5524
5759
|
const intent = row.intent ?? null;
|
|
5525
5760
|
const outcome = row.outcome ?? null;
|
|
5526
5761
|
const domain = row.domain ?? null;
|
|
@@ -5536,15 +5771,16 @@ async function flushBatch() {
|
|
|
5536
5771
|
const audience = row.audience ?? null;
|
|
5537
5772
|
const languageType = row.language_type ?? null;
|
|
5538
5773
|
const parentMemoryId = row.parent_memory_id ?? null;
|
|
5774
|
+
const procedureFor = row.procedure_for ?? null;
|
|
5539
5775
|
const cols = `id, agent_id, agent_role, session_id, timestamp,
|
|
5540
5776
|
tool_name, project_name,
|
|
5541
5777
|
has_error, raw_text, vector, version, task_id, importance, status,
|
|
5542
5778
|
confidence, last_accessed,
|
|
5543
5779
|
workspace_id, document_id, user_id, char_offset, page_number,
|
|
5544
|
-
source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
|
|
5780
|
+
source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
|
|
5545
5781
|
intent, outcome, domain, referenced_entities, retrieval_count,
|
|
5546
5782
|
chain_position, review_status, context_window_pct, file_paths, commit_hash,
|
|
5547
|
-
duration_ms, token_cost, audience, language_type, parent_memory_id`;
|
|
5783
|
+
duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for`;
|
|
5548
5784
|
const metaArgs = [
|
|
5549
5785
|
intent,
|
|
5550
5786
|
outcome,
|
|
@@ -5560,7 +5796,8 @@ async function flushBatch() {
|
|
|
5560
5796
|
tokenCost,
|
|
5561
5797
|
audience,
|
|
5562
5798
|
languageType,
|
|
5563
|
-
parentMemoryId
|
|
5799
|
+
parentMemoryId,
|
|
5800
|
+
procedureFor
|
|
5564
5801
|
];
|
|
5565
5802
|
const baseArgs = [
|
|
5566
5803
|
row.id,
|
|
@@ -5589,15 +5826,17 @@ async function flushBatch() {
|
|
|
5589
5826
|
sourceType,
|
|
5590
5827
|
tier,
|
|
5591
5828
|
supersedesId,
|
|
5829
|
+
validFrom,
|
|
5830
|
+
invalidAt,
|
|
5592
5831
|
draft,
|
|
5593
5832
|
memoryType,
|
|
5594
5833
|
trajectory,
|
|
5595
|
-
|
|
5834
|
+
contentHash2
|
|
5596
5835
|
];
|
|
5597
5836
|
return {
|
|
5598
5837
|
sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
|
|
5599
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
5600
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5838
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
5839
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5601
5840
|
args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
|
|
5602
5841
|
};
|
|
5603
5842
|
};
|
|
@@ -5713,6 +5952,12 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
5713
5952
|
AND vector IS NOT NULL${statusFilter}${draftFilter}
|
|
5714
5953
|
AND COALESCE(confidence, 0.7) >= 0.3`;
|
|
5715
5954
|
const args = [agentId];
|
|
5955
|
+
if (options?.asOf) {
|
|
5956
|
+
sql += ` AND (valid_from IS NULL OR valid_from <= ?) AND (invalid_at IS NULL OR invalid_at > ?)`;
|
|
5957
|
+
args.push(options.asOf, options.asOf);
|
|
5958
|
+
} else {
|
|
5959
|
+
sql += ` AND invalid_at IS NULL`;
|
|
5960
|
+
}
|
|
5716
5961
|
const scope = buildWikiScopeFilter(options, "");
|
|
5717
5962
|
sql += scope.clause;
|
|
5718
5963
|
args.push(...scope.args);
|
|
@@ -6090,6 +6335,21 @@ process.stdin.on("end", async () => {
|
|
|
6090
6335
|
JSON.parse(input);
|
|
6091
6336
|
const agent = getActiveAgent();
|
|
6092
6337
|
const sections = [];
|
|
6338
|
+
if (agent.agentId !== "default") {
|
|
6339
|
+
try {
|
|
6340
|
+
const { getIdentityInjection: getIdentityInjection2 } = await Promise.resolve().then(() => (init_identity(), identity_exports));
|
|
6341
|
+
const identity = getIdentityInjection2(agent.agentId);
|
|
6342
|
+
if (identity) {
|
|
6343
|
+
sections.push(`## Role Re-Injection (post-compaction)
|
|
6344
|
+
You are **${agent.agentId}** (${agent.agentRole}). Your identity and responsibilities:
|
|
6345
|
+
|
|
6346
|
+
${identity}`);
|
|
6347
|
+
process.stderr.write(`[post-compact] Re-injecting identity for ${agent.agentId}
|
|
6348
|
+
`);
|
|
6349
|
+
}
|
|
6350
|
+
} catch {
|
|
6351
|
+
}
|
|
6352
|
+
}
|
|
6093
6353
|
try {
|
|
6094
6354
|
const { fastDbInit: fastDbInit2 } = await Promise.resolve().then(() => (init_fast_db_init(), fast_db_init_exports));
|
|
6095
6355
|
await fastDbInit2();
|