@askexenow/exe-os 0.9.93 → 0.9.95
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 +121 -13
- package/dist/bin/cli.js +1561 -466
- package/dist/bin/customer-readiness.js +61 -0
- package/dist/bin/exe-agent.js +17 -3
- package/dist/bin/exe-assign.js +75 -9
- package/dist/bin/exe-boot.js +114 -12
- package/dist/bin/exe-call.js +17 -3
- package/dist/bin/exe-cloud.js +76 -10
- package/dist/bin/exe-dispatch.js +136 -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 +135 -18
- package/dist/bin/exe-heartbeat.js +121 -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 +121 -13
- package/dist/bin/exe-pending-notifications.js +121 -13
- package/dist/bin/exe-pending-reviews.js +121 -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 +136 -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 +121 -13
- package/dist/bin/exe-support.js +1 -0
- package/dist/bin/exe-team.js +75 -9
- package/dist/bin/git-sweep.js +136 -18
- package/dist/bin/graph-backfill.js +65 -8
- package/dist/bin/graph-export.js +75 -9
- package/dist/bin/intercom-check.js +136 -18
- package/dist/bin/scan-tasks.js +136 -18
- package/dist/bin/setup.js +55 -4
- package/dist/bin/shard-migrate.js +65 -8
- package/dist/bin/stack-update.js +5 -6
- package/dist/bin/update.js +1 -1
- package/dist/gateway/index.js +136 -18
- package/dist/hooks/bug-report-worker.js +136 -18
- package/dist/hooks/codex-stop-task-finalizer.js +126 -14
- package/dist/hooks/commit-complete.js +136 -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 +313 -50
- package/dist/hooks/post-tool-combined.js +436 -13
- package/dist/hooks/pre-compact.js +136 -18
- package/dist/hooks/pre-tool-use.js +121 -13
- package/dist/hooks/prompt-submit.js +194 -19
- package/dist/hooks/session-end.js +136 -18
- package/dist/hooks/session-start.js +146 -13
- package/dist/hooks/stop.js +121 -13
- package/dist/hooks/subagent-stop.js +121 -13
- package/dist/hooks/summary-worker.js +99 -7
- package/dist/index.js +136 -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 +916 -42
- package/dist/lib/hybrid-search.js +100 -9
- package/dist/lib/license.js +1 -1
- package/dist/lib/messaging.js +43 -4
- package/dist/lib/schedules.js +54 -3
- package/dist/lib/store.js +75 -9
- package/dist/lib/tasks.js +61 -9
- package/dist/lib/tmux-routing.js +61 -9
- package/dist/mcp/server.js +878 -42
- package/dist/mcp/tools/create-task.js +70 -12
- package/dist/mcp/tools/list-tasks.js +49 -5
- package/dist/mcp/tools/send-message.js +43 -4
- package/dist/mcp/tools/update-task.js +61 -9
- package/dist/runtime/index.js +136 -18
- package/dist/tui/App.js +135 -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;
|
|
@@ -3481,9 +3522,13 @@ function getParentExe(sessionKey) {
|
|
|
3481
3522
|
}
|
|
3482
3523
|
}
|
|
3483
3524
|
function resolveExeSession() {
|
|
3525
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
3526
|
+
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
3527
|
+
}
|
|
3484
3528
|
const mySession = getMySession();
|
|
3485
3529
|
if (!mySession) return null;
|
|
3486
3530
|
const fromSessionName = extractRootExe(mySession);
|
|
3531
|
+
let candidate = null;
|
|
3487
3532
|
try {
|
|
3488
3533
|
const key = getSessionKey();
|
|
3489
3534
|
const parentExe = getParentExe(key);
|
|
@@ -3494,13 +3539,47 @@ function resolveExeSession() {
|
|
|
3494
3539
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
3495
3540
|
`
|
|
3496
3541
|
);
|
|
3497
|
-
|
|
3542
|
+
candidate = fromSessionName;
|
|
3543
|
+
} else {
|
|
3544
|
+
candidate = fromCache;
|
|
3498
3545
|
}
|
|
3499
|
-
return fromCache;
|
|
3500
3546
|
}
|
|
3501
3547
|
} catch {
|
|
3502
3548
|
}
|
|
3503
|
-
|
|
3549
|
+
if (!candidate) {
|
|
3550
|
+
candidate = fromSessionName ?? mySession;
|
|
3551
|
+
}
|
|
3552
|
+
if (candidate && isRootSession(candidate)) {
|
|
3553
|
+
try {
|
|
3554
|
+
const transport = getTransport();
|
|
3555
|
+
const liveSessions = transport.listSessions();
|
|
3556
|
+
if (!liveSessions.includes(candidate)) {
|
|
3557
|
+
const liveRoots = liveSessions.filter((s) => isRootSession(s));
|
|
3558
|
+
if (liveRoots.length === 1) {
|
|
3559
|
+
process.stderr.write(
|
|
3560
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. Using live coordinator "${liveRoots[0]}".
|
|
3561
|
+
`
|
|
3562
|
+
);
|
|
3563
|
+
return liveRoots[0];
|
|
3564
|
+
} else if (liveRoots.length > 1) {
|
|
3565
|
+
const base = candidate.replace(/\d+$/, "");
|
|
3566
|
+
const match = liveRoots.find((s) => s.startsWith(base));
|
|
3567
|
+
const chosen = match ?? liveRoots[0];
|
|
3568
|
+
process.stderr.write(
|
|
3569
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. ${liveRoots.length} live roots found, using "${chosen}".
|
|
3570
|
+
`
|
|
3571
|
+
);
|
|
3572
|
+
return chosen;
|
|
3573
|
+
}
|
|
3574
|
+
process.stderr.write(
|
|
3575
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead and no live coordinator found.
|
|
3576
|
+
`
|
|
3577
|
+
);
|
|
3578
|
+
}
|
|
3579
|
+
} catch {
|
|
3580
|
+
}
|
|
3581
|
+
}
|
|
3582
|
+
return candidate;
|
|
3504
3583
|
}
|
|
3505
3584
|
var SPAWN_LOCK_DIR, SESSION_CACHE, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS;
|
|
3506
3585
|
var init_tmux_routing = __esm({
|
|
@@ -3550,17 +3629,157 @@ var init_task_scope = __esm({
|
|
|
3550
3629
|
}
|
|
3551
3630
|
});
|
|
3552
3631
|
|
|
3632
|
+
// src/lib/identity.ts
|
|
3633
|
+
var identity_exports = {};
|
|
3634
|
+
__export(identity_exports, {
|
|
3635
|
+
getIdentity: () => getIdentity,
|
|
3636
|
+
getIdentityInjection: () => getIdentityInjection,
|
|
3637
|
+
identityPath: () => identityPath,
|
|
3638
|
+
listIdentities: () => listIdentities,
|
|
3639
|
+
updateIdentity: () => updateIdentity
|
|
3640
|
+
});
|
|
3641
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync7, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "fs";
|
|
3642
|
+
import { readdirSync as readdirSync3 } from "fs";
|
|
3643
|
+
import path14 from "path";
|
|
3644
|
+
import { createHash } from "crypto";
|
|
3645
|
+
function ensureDir() {
|
|
3646
|
+
if (!existsSync12(IDENTITY_DIR2)) {
|
|
3647
|
+
mkdirSync7(IDENTITY_DIR2, { recursive: true });
|
|
3648
|
+
}
|
|
3649
|
+
}
|
|
3650
|
+
function identityPath(agentId) {
|
|
3651
|
+
return path14.join(IDENTITY_DIR2, `${agentId}.md`);
|
|
3652
|
+
}
|
|
3653
|
+
function sanitizeIdentityBody(body) {
|
|
3654
|
+
return body.replace(/<!--[\s\S]*?-->/g, "").trim();
|
|
3655
|
+
}
|
|
3656
|
+
function parseFrontmatter(raw) {
|
|
3657
|
+
const match = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
3658
|
+
if (!match) {
|
|
3659
|
+
return {
|
|
3660
|
+
frontmatter: {
|
|
3661
|
+
role: "unknown",
|
|
3662
|
+
title: "Unknown",
|
|
3663
|
+
agent_id: "unknown",
|
|
3664
|
+
org_level: "specialist",
|
|
3665
|
+
created_by: "system",
|
|
3666
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
3667
|
+
},
|
|
3668
|
+
body: sanitizeIdentityBody(raw)
|
|
3669
|
+
};
|
|
3670
|
+
}
|
|
3671
|
+
const yamlStr = match[1];
|
|
3672
|
+
const body = sanitizeIdentityBody(match[2]);
|
|
3673
|
+
const fm = {};
|
|
3674
|
+
for (const line of yamlStr.split("\n")) {
|
|
3675
|
+
const kv = line.match(/^(\w+):\s*(.+)$/);
|
|
3676
|
+
if (kv) fm[kv[1]] = kv[2].trim();
|
|
3677
|
+
}
|
|
3678
|
+
return {
|
|
3679
|
+
frontmatter: {
|
|
3680
|
+
role: fm.role ?? "unknown",
|
|
3681
|
+
title: fm.title ?? "Unknown",
|
|
3682
|
+
agent_id: fm.agent_id ?? "unknown",
|
|
3683
|
+
org_level: fm.org_level ?? "specialist",
|
|
3684
|
+
created_by: fm.created_by ?? "system",
|
|
3685
|
+
updated_at: fm.updated_at ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
3686
|
+
},
|
|
3687
|
+
body
|
|
3688
|
+
};
|
|
3689
|
+
}
|
|
3690
|
+
function contentHash(content) {
|
|
3691
|
+
return createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
3692
|
+
}
|
|
3693
|
+
function getIdentity(agentId) {
|
|
3694
|
+
const filePath = identityPath(agentId);
|
|
3695
|
+
if (!existsSync12(filePath)) return null;
|
|
3696
|
+
const raw = readFileSync11(filePath, "utf-8");
|
|
3697
|
+
const { frontmatter, body } = parseFrontmatter(raw);
|
|
3698
|
+
return {
|
|
3699
|
+
agentId,
|
|
3700
|
+
frontmatter,
|
|
3701
|
+
body,
|
|
3702
|
+
raw,
|
|
3703
|
+
contentHash: contentHash(raw)
|
|
3704
|
+
};
|
|
3705
|
+
}
|
|
3706
|
+
async function updateIdentity(agentId, content, updatedBy) {
|
|
3707
|
+
ensureDir();
|
|
3708
|
+
const filePath = identityPath(agentId);
|
|
3709
|
+
const hash = contentHash(content);
|
|
3710
|
+
writeFileSync8(filePath, content, "utf-8");
|
|
3711
|
+
try {
|
|
3712
|
+
const client = getClient();
|
|
3713
|
+
await client.execute({
|
|
3714
|
+
sql: `INSERT INTO identity (agent_id, content_hash, updated_at, updated_by)
|
|
3715
|
+
VALUES (?, ?, ?, ?)
|
|
3716
|
+
ON CONFLICT(agent_id) DO UPDATE SET
|
|
3717
|
+
content_hash = excluded.content_hash,
|
|
3718
|
+
updated_at = excluded.updated_at,
|
|
3719
|
+
updated_by = excluded.updated_by`,
|
|
3720
|
+
args: [agentId, hash, (/* @__PURE__ */ new Date()).toISOString(), updatedBy]
|
|
3721
|
+
});
|
|
3722
|
+
} catch {
|
|
3723
|
+
}
|
|
3724
|
+
}
|
|
3725
|
+
function listIdentities() {
|
|
3726
|
+
ensureDir();
|
|
3727
|
+
const files = readdirSync3(IDENTITY_DIR2).filter((f) => f.endsWith(".md"));
|
|
3728
|
+
const results = [];
|
|
3729
|
+
for (const file of files) {
|
|
3730
|
+
const agentId = file.replace(".md", "");
|
|
3731
|
+
const identity = getIdentity(agentId);
|
|
3732
|
+
if (!identity) continue;
|
|
3733
|
+
const lines = identity.body.split("\n").filter((l) => l.trim() && !l.startsWith("#"));
|
|
3734
|
+
const summary = lines[0]?.trim().slice(0, 120) ?? identity.frontmatter.title;
|
|
3735
|
+
results.push({
|
|
3736
|
+
agentId,
|
|
3737
|
+
// User-facing/team-facing title only. `frontmatter.role` is internal
|
|
3738
|
+
// routing metadata and must not leak as an external title.
|
|
3739
|
+
title: identity.frontmatter.title,
|
|
3740
|
+
summary
|
|
3741
|
+
});
|
|
3742
|
+
}
|
|
3743
|
+
return results;
|
|
3744
|
+
}
|
|
3745
|
+
function getIdentityInjection(agentId) {
|
|
3746
|
+
const own = getIdentity(agentId);
|
|
3747
|
+
const all = listIdentities();
|
|
3748
|
+
const parts = [];
|
|
3749
|
+
if (own) {
|
|
3750
|
+
parts.push(`## Your Identity (exe.md)
|
|
3751
|
+
These define WHO YOU ARE. Non-negotiable. Permanent.
|
|
3752
|
+
|
|
3753
|
+
${own.body}`);
|
|
3754
|
+
}
|
|
3755
|
+
const teamLines = all.filter((a) => a.agentId !== agentId).map((a) => `- ${a.agentId} (${a.title}): ${a.summary}`);
|
|
3756
|
+
if (teamLines.length > 0) {
|
|
3757
|
+
parts.push(`## Team Identities
|
|
3758
|
+
${teamLines.join("\n")}`);
|
|
3759
|
+
}
|
|
3760
|
+
return parts.join("\n\n");
|
|
3761
|
+
}
|
|
3762
|
+
var IDENTITY_DIR2;
|
|
3763
|
+
var init_identity = __esm({
|
|
3764
|
+
"src/lib/identity.ts"() {
|
|
3765
|
+
"use strict";
|
|
3766
|
+
init_config();
|
|
3767
|
+
init_database();
|
|
3768
|
+
IDENTITY_DIR2 = path14.join(EXE_AI_DIR, "identity");
|
|
3769
|
+
}
|
|
3770
|
+
});
|
|
3771
|
+
|
|
3553
3772
|
// src/lib/keychain.ts
|
|
3554
3773
|
import { readFile as readFile3, writeFile as writeFile3, unlink, mkdir as mkdir3, chmod as chmod2 } from "fs/promises";
|
|
3555
|
-
import { existsSync as
|
|
3774
|
+
import { existsSync as existsSync13, statSync as statSync2 } from "fs";
|
|
3556
3775
|
import { execSync as execSync6 } from "child_process";
|
|
3557
|
-
import
|
|
3776
|
+
import path15 from "path";
|
|
3558
3777
|
import os10 from "os";
|
|
3559
3778
|
function getKeyDir() {
|
|
3560
|
-
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ??
|
|
3779
|
+
return process.env.EXE_OS_DIR ?? process.env.EXE_MEM_DIR ?? path15.join(os10.homedir(), ".exe-os");
|
|
3561
3780
|
}
|
|
3562
3781
|
function getKeyPath() {
|
|
3563
|
-
return
|
|
3782
|
+
return path15.join(getKeyDir(), "master.key");
|
|
3564
3783
|
}
|
|
3565
3784
|
function nativeKeychainAllowed() {
|
|
3566
3785
|
return process.env.EXE_OS_DISABLE_NATIVE_KEYCHAIN !== "1";
|
|
@@ -3591,7 +3810,7 @@ function isRootOnlyTrustedServerKeyFile(keyPath) {
|
|
|
3591
3810
|
if (!st.isFile() || (st.mode & 63) !== 0) return false;
|
|
3592
3811
|
if (uid === 0) return true;
|
|
3593
3812
|
const exeOsDir = process.env.EXE_OS_DIR;
|
|
3594
|
-
return Boolean(exeOsDir &&
|
|
3813
|
+
return Boolean(exeOsDir && path15.resolve(keyPath).startsWith(path15.resolve(exeOsDir) + path15.sep));
|
|
3595
3814
|
} catch {
|
|
3596
3815
|
return false;
|
|
3597
3816
|
}
|
|
@@ -3703,8 +3922,8 @@ function deriveMachineKey() {
|
|
|
3703
3922
|
}
|
|
3704
3923
|
function readMachineId() {
|
|
3705
3924
|
try {
|
|
3706
|
-
const { readFileSync:
|
|
3707
|
-
return
|
|
3925
|
+
const { readFileSync: readFileSync12 } = __require("fs");
|
|
3926
|
+
return readFileSync12("/etc/machine-id", "utf-8").trim();
|
|
3708
3927
|
} catch {
|
|
3709
3928
|
return "";
|
|
3710
3929
|
}
|
|
@@ -3788,7 +4007,7 @@ async function getMasterKey() {
|
|
|
3788
4007
|
}
|
|
3789
4008
|
}
|
|
3790
4009
|
const keyPath = getKeyPath();
|
|
3791
|
-
if (!
|
|
4010
|
+
if (!existsSync13(keyPath)) {
|
|
3792
4011
|
process.stderr.write(
|
|
3793
4012
|
`[keychain] Key not found at ${keyPath} (HOME=${os10.homedir()}, EXE_OS_DIR=${process.env.EXE_OS_DIR ?? "unset"})
|
|
3794
4013
|
`
|
|
@@ -3914,7 +4133,7 @@ var init_state_bus = __esm({
|
|
|
3914
4133
|
});
|
|
3915
4134
|
|
|
3916
4135
|
// src/lib/memory-write-governor.ts
|
|
3917
|
-
import { createHash } from "crypto";
|
|
4136
|
+
import { createHash as createHash2 } from "crypto";
|
|
3918
4137
|
function normalizeMemoryText(text) {
|
|
3919
4138
|
return text.replace(/\r\n/g, "\n").replace(/[ \t]+$/gm, "").replace(/\n{4,}/g, "\n\n\n").trim();
|
|
3920
4139
|
}
|
|
@@ -3949,7 +4168,7 @@ function shouldSkipEmbedding(input2) {
|
|
|
3949
4168
|
return false;
|
|
3950
4169
|
}
|
|
3951
4170
|
function hashMemoryContent(text) {
|
|
3952
|
-
return
|
|
4171
|
+
return createHash2("sha256").update(normalizeMemoryText(text)).digest("hex");
|
|
3953
4172
|
}
|
|
3954
4173
|
function scopedDedupArgs(input2) {
|
|
3955
4174
|
return [input2.contentHash, input2.agentId, input2.projectName, input2.memoryType];
|
|
@@ -4021,10 +4240,10 @@ async function runPostWriteMemoryHygiene(memoryId) {
|
|
|
4021
4240
|
const row = current.rows[0];
|
|
4022
4241
|
if (!row) return;
|
|
4023
4242
|
const memoryType = String(row.memory_type ?? "raw");
|
|
4024
|
-
const
|
|
4243
|
+
const contentHash2 = row.content_hash ? String(row.content_hash) : null;
|
|
4025
4244
|
const agentId = String(row.agent_id);
|
|
4026
4245
|
const projectName = String(row.project_name);
|
|
4027
|
-
if (
|
|
4246
|
+
if (contentHash2) {
|
|
4028
4247
|
await client.execute({
|
|
4029
4248
|
sql: `UPDATE memories
|
|
4030
4249
|
SET status = 'deleted',
|
|
@@ -4035,7 +4254,7 @@ async function runPostWriteMemoryHygiene(memoryId) {
|
|
|
4035
4254
|
AND project_name = ?
|
|
4036
4255
|
AND COALESCE(memory_type, 'raw') = ?
|
|
4037
4256
|
AND COALESCE(status, 'active') = 'active'`,
|
|
4038
|
-
args: [memoryId,
|
|
4257
|
+
args: [memoryId, contentHash2, agentId, projectName, memoryType]
|
|
4039
4258
|
});
|
|
4040
4259
|
}
|
|
4041
4260
|
const supersedesId = row.supersedes_id ? String(row.supersedes_id) : null;
|
|
@@ -4122,13 +4341,13 @@ __export(shard_manager_exports, {
|
|
|
4122
4341
|
listShards: () => listShards,
|
|
4123
4342
|
shardExists: () => shardExists
|
|
4124
4343
|
});
|
|
4125
|
-
import
|
|
4126
|
-
import { existsSync as
|
|
4344
|
+
import path16 from "path";
|
|
4345
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync8, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync3 } from "fs";
|
|
4127
4346
|
import { createClient as createClient2 } from "@libsql/client";
|
|
4128
4347
|
function initShardManager(encryptionKey) {
|
|
4129
4348
|
_encryptionKey = encryptionKey;
|
|
4130
|
-
if (!
|
|
4131
|
-
|
|
4349
|
+
if (!existsSync14(SHARDS_DIR)) {
|
|
4350
|
+
mkdirSync8(SHARDS_DIR, { recursive: true });
|
|
4132
4351
|
}
|
|
4133
4352
|
_shardingEnabled = true;
|
|
4134
4353
|
if (_evictionTimer) clearInterval(_evictionTimer);
|
|
@@ -4157,7 +4376,7 @@ function getShardClient(projectName) {
|
|
|
4157
4376
|
while (_shards.size >= MAX_OPEN_SHARDS) {
|
|
4158
4377
|
evictLRU();
|
|
4159
4378
|
}
|
|
4160
|
-
const dbPath =
|
|
4379
|
+
const dbPath = path16.join(SHARDS_DIR, `${safeName}.db`);
|
|
4161
4380
|
const client = createClient2({
|
|
4162
4381
|
url: `file:${dbPath}`,
|
|
4163
4382
|
encryptionKey: _encryptionKey
|
|
@@ -4168,14 +4387,14 @@ function getShardClient(projectName) {
|
|
|
4168
4387
|
}
|
|
4169
4388
|
function shardExists(projectName) {
|
|
4170
4389
|
const safeName = safeShardName(projectName);
|
|
4171
|
-
return
|
|
4390
|
+
return existsSync14(path16.join(SHARDS_DIR, `${safeName}.db`));
|
|
4172
4391
|
}
|
|
4173
4392
|
function safeShardName(projectName) {
|
|
4174
4393
|
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
4175
4394
|
}
|
|
4176
4395
|
function listShards() {
|
|
4177
|
-
if (!
|
|
4178
|
-
return
|
|
4396
|
+
if (!existsSync14(SHARDS_DIR)) return [];
|
|
4397
|
+
return readdirSync4(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
4179
4398
|
}
|
|
4180
4399
|
async function auditShardHealth(options = {}) {
|
|
4181
4400
|
if (!_encryptionKey) {
|
|
@@ -4186,7 +4405,7 @@ async function auditShardHealth(options = {}) {
|
|
|
4186
4405
|
const names = listShards();
|
|
4187
4406
|
const shards = [];
|
|
4188
4407
|
for (const name of names) {
|
|
4189
|
-
const dbPath =
|
|
4408
|
+
const dbPath = path16.join(SHARDS_DIR, `${name}.db`);
|
|
4190
4409
|
const stat = statSync3(dbPath);
|
|
4191
4410
|
const item = {
|
|
4192
4411
|
name,
|
|
@@ -4221,7 +4440,7 @@ async function auditShardHealth(options = {}) {
|
|
|
4221
4440
|
_shards.delete(name);
|
|
4222
4441
|
_shardLastAccess.delete(name);
|
|
4223
4442
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
4224
|
-
const archivedPath =
|
|
4443
|
+
const archivedPath = path16.join(SHARDS_DIR, `${name}.db.broken-${stamp}`);
|
|
4225
4444
|
renameSync4(dbPath, archivedPath);
|
|
4226
4445
|
item.archivedPath = archivedPath;
|
|
4227
4446
|
}
|
|
@@ -4438,11 +4657,11 @@ async function getReadyShardClient(projectName) {
|
|
|
4438
4657
|
client.close();
|
|
4439
4658
|
_shards.delete(safeName);
|
|
4440
4659
|
_shardLastAccess.delete(safeName);
|
|
4441
|
-
const dbPath =
|
|
4442
|
-
if (
|
|
4660
|
+
const dbPath = path16.join(SHARDS_DIR, `${safeName}.db`);
|
|
4661
|
+
if (existsSync14(dbPath)) {
|
|
4443
4662
|
const stat = statSync3(dbPath);
|
|
4444
4663
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
4445
|
-
const archivedPath =
|
|
4664
|
+
const archivedPath = path16.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
4446
4665
|
renameSync4(dbPath, archivedPath);
|
|
4447
4666
|
process.stderr.write(
|
|
4448
4667
|
`[shard-manager] Archived unreadable shard ${safeName}: ${archivedPath} (${stat.size} bytes, mtime ${stat.mtime.toISOString()})
|
|
@@ -4510,7 +4729,7 @@ var init_shard_manager = __esm({
|
|
|
4510
4729
|
"src/lib/shard-manager.ts"() {
|
|
4511
4730
|
"use strict";
|
|
4512
4731
|
init_config();
|
|
4513
|
-
SHARDS_DIR =
|
|
4732
|
+
SHARDS_DIR = path16.join(EXE_AI_DIR, "shards");
|
|
4514
4733
|
SHARD_IDLE_MS = 5 * 60 * 1e3;
|
|
4515
4734
|
MAX_OPEN_SHARDS = 10;
|
|
4516
4735
|
EVICTION_INTERVAL_MS = 60 * 1e3;
|
|
@@ -4636,6 +4855,20 @@ var init_platform_procedures = __esm({
|
|
|
4636
4855
|
priority: "p1",
|
|
4637
4856
|
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
4857
|
},
|
|
4858
|
+
// --- Tool guidance ---
|
|
4859
|
+
{
|
|
4860
|
+
title: "How to use company_actions \u2014 execute business actions through gateway connectors",
|
|
4861
|
+
domain: "tools",
|
|
4862
|
+
priority: "p2",
|
|
4863
|
+
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."
|
|
4864
|
+
},
|
|
4865
|
+
// --- Release awareness ---
|
|
4866
|
+
{
|
|
4867
|
+
title: "What's New check \u2014 surface new features after update",
|
|
4868
|
+
domain: "support",
|
|
4869
|
+
priority: "p1",
|
|
4870
|
+
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."
|
|
4871
|
+
},
|
|
4639
4872
|
// --- Platform vs Customer ownership ---
|
|
4640
4873
|
{
|
|
4641
4874
|
title: "What the platform provides vs what you customize",
|
|
@@ -4724,13 +4957,13 @@ var init_platform_procedures = __esm({
|
|
|
4724
4957
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
4725
4958
|
domain: "tool-use",
|
|
4726
4959
|
priority: "p1",
|
|
4727
|
-
content: `memory(action="recall") / recall_my_memory: search
|
|
4960
|
+
content: `memory(action="recall") / recall_my_memory: search memories (semantic + FTS). Params: as_of (bi-temporal \u2014 what did I know at time X?), kind (decision|procedure|observation|raw|conversation|behavior), retrieval_mode (all|decisions_only|procedures_only|operational|recent_high_value). memory(action="ask_team") / ask_team_memory: search a colleague's memories. memory(action="store") / store_memory: persist a memory. Params: kind, procedure_for (domain tag for procedures). memory(action="commit") / commit_memory: high-importance, survives consolidation. Requires summary. memory(action="search") / search_everything: unified search across memories, tasks, entities, conversations. memory(action="session_context") / get_session_context: temporal window. Requires session_id + target_timestamp. memory(action="get_by_id"): fetch one memory by UUID with full untruncated text. memory(action="consolidate") / consolidate_memories: merge duplicate/related memories. memory(action="cardinality") / get_memory_cardinality: count memories per agent. memory(action="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
4961
|
},
|
|
4729
4962
|
{
|
|
4730
4963
|
title: "MCP tools \u2014 task orchestration",
|
|
4731
4964
|
domain: "tool-use",
|
|
4732
4965
|
priority: "p1",
|
|
4733
|
-
content: 'task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. 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.'
|
|
4966
|
+
content: 'task(action="create") / create_task: dispatch work (title, assigned_to, context). The ONLY dispatch path. Auto-spawns session. Params: blocked_by (task ID for dependency), parent_task_id (subtask hierarchy), reviewer, complexity (routine|standard|complex|critical), budget_tokens (max token cap), budget_fallback_model, spawn_runtime (override runtime: claude|codex|opencode), spawn_model (override model). 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
4967
|
},
|
|
4735
4968
|
{
|
|
4736
4969
|
title: "MCP tools \u2014 knowledge graph (GraphRAG)",
|
|
@@ -4760,7 +4993,7 @@ var init_platform_procedures = __esm({
|
|
|
4760
4993
|
title: "MCP tools \u2014 admin, config, and operations",
|
|
4761
4994
|
domain: "tool-use",
|
|
4762
4995
|
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.'
|
|
4996
|
+
content: 'config(action="list_employees"): view roster. config(action="set_agent_config"): view or change per-agent runtime + model. Call with no args to show all agents. 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. Supports cloud_action param: status|sync|reupload. config(action="memory_audit"): health check (dupes, null vectors). config(action="run_consolidation"): trigger memory consolidation. config(action="worker_gate"): check spawn slot availability \u2014 alive/stale/reserved counts vs max. Use before dispatching. config(action="auto_wake_status"): orphaned tasks, blocked tasks, auto-wake retry status. config(action="orchestration_phase"): view/change org phase (phase_1_coo|phase_2_executives|phase_3_parallel_org). 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="pending_work_summary"): pending reviews + messages + notifications in one call. diagnostics(action="rename_employee"): rename an agent across all systems (roster, identity, DB, symlinks). diagnostics(action="tool_search"): semantic tool discovery \u2014 find relevant MCP tools by natural language query. diagnostics(action="drift"): identity drift detection \u2014 score how far an agent has drifted from its role. mcp_ping(): daemon health + license status + tool usage stats.'
|
|
4764
4997
|
}
|
|
4765
4998
|
];
|
|
4766
4999
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -4847,9 +5080,9 @@ __export(memory_cards_exports, {
|
|
|
4847
5080
|
insertMemoryCardsForBatch: () => insertMemoryCardsForBatch,
|
|
4848
5081
|
searchMemoryCards: () => searchMemoryCards
|
|
4849
5082
|
});
|
|
4850
|
-
import { createHash as
|
|
5083
|
+
import { createHash as createHash3 } from "crypto";
|
|
4851
5084
|
function stableId(memoryId, type, content) {
|
|
4852
|
-
return
|
|
5085
|
+
return createHash3("sha256").update(`${memoryId}:${type}:${content}`).digest("hex").slice(0, 32);
|
|
4853
5086
|
}
|
|
4854
5087
|
function cleanText(text) {
|
|
4855
5088
|
return text.replace(/```[\s\S]*?```/g, " ").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
@@ -5012,9 +5245,9 @@ __export(agentic_ontology_exports, {
|
|
|
5012
5245
|
ontologyPayload: () => ontologyPayload,
|
|
5013
5246
|
stableId: () => stableId2
|
|
5014
5247
|
});
|
|
5015
|
-
import { createHash as
|
|
5248
|
+
import { createHash as createHash4 } from "crypto";
|
|
5016
5249
|
function stableId2(...parts) {
|
|
5017
|
-
return
|
|
5250
|
+
return createHash4("sha256").update(parts.map((p) => String(p ?? "")).join("::")).digest("hex").slice(0, 32);
|
|
5018
5251
|
}
|
|
5019
5252
|
function clean(text, max = 240) {
|
|
5020
5253
|
return text.replace(/\u0000/g, "").replace(/```[\s\S]*?```/g, " ").replace(/\s+/g, " ").trim().slice(0, max);
|
|
@@ -5400,16 +5633,16 @@ async function writeMemory(record) {
|
|
|
5400
5633
|
const governed = governMemoryRecord(record);
|
|
5401
5634
|
if (governed.shouldDrop) return;
|
|
5402
5635
|
record = governed.record;
|
|
5403
|
-
const
|
|
5636
|
+
const contentHash2 = governed.contentHash;
|
|
5404
5637
|
const memoryType = record.memory_type ?? "raw";
|
|
5405
5638
|
if (_pendingRecords.some(
|
|
5406
|
-
(r) => r.content_hash ===
|
|
5639
|
+
(r) => r.content_hash === contentHash2 && r.agent_id === record.agent_id && r.project_name === record.project_name && (r.memory_type ?? "raw") === memoryType
|
|
5407
5640
|
)) {
|
|
5408
5641
|
return;
|
|
5409
5642
|
}
|
|
5410
5643
|
try {
|
|
5411
5644
|
const existing = await findScopedDuplicate({
|
|
5412
|
-
contentHash,
|
|
5645
|
+
contentHash: contentHash2,
|
|
5413
5646
|
agentId: record.agent_id,
|
|
5414
5647
|
projectName: record.project_name,
|
|
5415
5648
|
memoryType
|
|
@@ -5444,10 +5677,12 @@ async function writeMemory(record) {
|
|
|
5444
5677
|
source_type: record.source_type ?? null,
|
|
5445
5678
|
tier: record.tier ?? classifyTier(record),
|
|
5446
5679
|
supersedes_id: record.supersedes_id ?? null,
|
|
5680
|
+
valid_from: record.valid_from ?? record.timestamp,
|
|
5681
|
+
invalid_at: record.invalid_at ?? null,
|
|
5447
5682
|
draft: record.draft ? 1 : 0,
|
|
5448
5683
|
memory_type: memoryType,
|
|
5449
5684
|
trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
|
|
5450
|
-
content_hash:
|
|
5685
|
+
content_hash: contentHash2,
|
|
5451
5686
|
intent: record.intent ?? null,
|
|
5452
5687
|
outcome: record.outcome ?? null,
|
|
5453
5688
|
domain: record.domain ?? inferDomain(record),
|
|
@@ -5462,7 +5697,8 @@ async function writeMemory(record) {
|
|
|
5462
5697
|
token_cost: record.token_cost ?? null,
|
|
5463
5698
|
audience: record.audience ?? null,
|
|
5464
5699
|
language_type: record.language_type ?? inferLanguageType(record),
|
|
5465
|
-
parent_memory_id: record.parent_memory_id ?? null
|
|
5700
|
+
parent_memory_id: record.parent_memory_id ?? null,
|
|
5701
|
+
procedure_for: record.procedure_for ?? null
|
|
5466
5702
|
};
|
|
5467
5703
|
_pendingRecords.push(dbRow);
|
|
5468
5704
|
orgBus.emit({
|
|
@@ -5517,10 +5753,12 @@ async function flushBatch() {
|
|
|
5517
5753
|
const sourceType = row.source_type ?? null;
|
|
5518
5754
|
const tier = row.tier ?? 3;
|
|
5519
5755
|
const supersedesId = row.supersedes_id ?? null;
|
|
5756
|
+
const validFrom = row.valid_from ?? row.timestamp;
|
|
5757
|
+
const invalidAt = row.invalid_at ?? null;
|
|
5520
5758
|
const draft = row.draft ? 1 : 0;
|
|
5521
5759
|
const memoryType = row.memory_type ?? "raw";
|
|
5522
5760
|
const trajectory = row.trajectory ?? null;
|
|
5523
|
-
const
|
|
5761
|
+
const contentHash2 = row.content_hash ?? null;
|
|
5524
5762
|
const intent = row.intent ?? null;
|
|
5525
5763
|
const outcome = row.outcome ?? null;
|
|
5526
5764
|
const domain = row.domain ?? null;
|
|
@@ -5536,15 +5774,16 @@ async function flushBatch() {
|
|
|
5536
5774
|
const audience = row.audience ?? null;
|
|
5537
5775
|
const languageType = row.language_type ?? null;
|
|
5538
5776
|
const parentMemoryId = row.parent_memory_id ?? null;
|
|
5777
|
+
const procedureFor = row.procedure_for ?? null;
|
|
5539
5778
|
const cols = `id, agent_id, agent_role, session_id, timestamp,
|
|
5540
5779
|
tool_name, project_name,
|
|
5541
5780
|
has_error, raw_text, vector, version, task_id, importance, status,
|
|
5542
5781
|
confidence, last_accessed,
|
|
5543
5782
|
workspace_id, document_id, user_id, char_offset, page_number,
|
|
5544
|
-
source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
|
|
5783
|
+
source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
|
|
5545
5784
|
intent, outcome, domain, referenced_entities, retrieval_count,
|
|
5546
5785
|
chain_position, review_status, context_window_pct, file_paths, commit_hash,
|
|
5547
|
-
duration_ms, token_cost, audience, language_type, parent_memory_id`;
|
|
5786
|
+
duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for`;
|
|
5548
5787
|
const metaArgs = [
|
|
5549
5788
|
intent,
|
|
5550
5789
|
outcome,
|
|
@@ -5560,7 +5799,8 @@ async function flushBatch() {
|
|
|
5560
5799
|
tokenCost,
|
|
5561
5800
|
audience,
|
|
5562
5801
|
languageType,
|
|
5563
|
-
parentMemoryId
|
|
5802
|
+
parentMemoryId,
|
|
5803
|
+
procedureFor
|
|
5564
5804
|
];
|
|
5565
5805
|
const baseArgs = [
|
|
5566
5806
|
row.id,
|
|
@@ -5589,15 +5829,17 @@ async function flushBatch() {
|
|
|
5589
5829
|
sourceType,
|
|
5590
5830
|
tier,
|
|
5591
5831
|
supersedesId,
|
|
5832
|
+
validFrom,
|
|
5833
|
+
invalidAt,
|
|
5592
5834
|
draft,
|
|
5593
5835
|
memoryType,
|
|
5594
5836
|
trajectory,
|
|
5595
|
-
|
|
5837
|
+
contentHash2
|
|
5596
5838
|
];
|
|
5597
5839
|
return {
|
|
5598
5840
|
sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
|
|
5599
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
5600
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5841
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
5842
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5601
5843
|
args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
|
|
5602
5844
|
};
|
|
5603
5845
|
};
|
|
@@ -5713,6 +5955,12 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
5713
5955
|
AND vector IS NOT NULL${statusFilter}${draftFilter}
|
|
5714
5956
|
AND COALESCE(confidence, 0.7) >= 0.3`;
|
|
5715
5957
|
const args = [agentId];
|
|
5958
|
+
if (options?.asOf) {
|
|
5959
|
+
sql += ` AND (valid_from IS NULL OR valid_from <= ?) AND (invalid_at IS NULL OR invalid_at > ?)`;
|
|
5960
|
+
args.push(options.asOf, options.asOf);
|
|
5961
|
+
} else {
|
|
5962
|
+
sql += ` AND invalid_at IS NULL`;
|
|
5963
|
+
}
|
|
5716
5964
|
const scope = buildWikiScopeFilter(options, "");
|
|
5717
5965
|
sql += scope.clause;
|
|
5718
5966
|
args.push(...scope.args);
|
|
@@ -6090,6 +6338,21 @@ process.stdin.on("end", async () => {
|
|
|
6090
6338
|
JSON.parse(input);
|
|
6091
6339
|
const agent = getActiveAgent();
|
|
6092
6340
|
const sections = [];
|
|
6341
|
+
if (agent.agentId !== "default") {
|
|
6342
|
+
try {
|
|
6343
|
+
const { getIdentityInjection: getIdentityInjection2 } = await Promise.resolve().then(() => (init_identity(), identity_exports));
|
|
6344
|
+
const identity = getIdentityInjection2(agent.agentId);
|
|
6345
|
+
if (identity) {
|
|
6346
|
+
sections.push(`## Role Re-Injection (post-compaction)
|
|
6347
|
+
You are **${agent.agentId}** (${agent.agentRole}). Your identity and responsibilities:
|
|
6348
|
+
|
|
6349
|
+
${identity}`);
|
|
6350
|
+
process.stderr.write(`[post-compact] Re-injecting identity for ${agent.agentId}
|
|
6351
|
+
`);
|
|
6352
|
+
}
|
|
6353
|
+
} catch {
|
|
6354
|
+
}
|
|
6355
|
+
}
|
|
6093
6356
|
try {
|
|
6094
6357
|
const { fastDbInit: fastDbInit2 } = await Promise.resolve().then(() => (init_fast_db_init(), fast_db_init_exports));
|
|
6095
6358
|
await fastDbInit2();
|