@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
package/dist/runtime/index.js
CHANGED
|
@@ -3334,6 +3334,20 @@ async function ensureSchema() {
|
|
|
3334
3334
|
});
|
|
3335
3335
|
} catch {
|
|
3336
3336
|
}
|
|
3337
|
+
try {
|
|
3338
|
+
await client.execute({
|
|
3339
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
3340
|
+
args: []
|
|
3341
|
+
});
|
|
3342
|
+
} catch {
|
|
3343
|
+
}
|
|
3344
|
+
try {
|
|
3345
|
+
await client.execute({
|
|
3346
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
3347
|
+
args: []
|
|
3348
|
+
});
|
|
3349
|
+
} catch {
|
|
3350
|
+
}
|
|
3337
3351
|
await client.executeMultiple(`
|
|
3338
3352
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
3339
3353
|
content_text,
|
|
@@ -3585,6 +3599,22 @@ async function ensureSchema() {
|
|
|
3585
3599
|
);
|
|
3586
3600
|
} catch {
|
|
3587
3601
|
}
|
|
3602
|
+
for (const col of [
|
|
3603
|
+
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
3604
|
+
"ALTER TABLE memories ADD COLUMN invalid_at TEXT"
|
|
3605
|
+
]) {
|
|
3606
|
+
try {
|
|
3607
|
+
await client.execute(col);
|
|
3608
|
+
} catch {
|
|
3609
|
+
}
|
|
3610
|
+
}
|
|
3611
|
+
try {
|
|
3612
|
+
await client.execute({
|
|
3613
|
+
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3614
|
+
args: []
|
|
3615
|
+
});
|
|
3616
|
+
} catch {
|
|
3617
|
+
}
|
|
3588
3618
|
try {
|
|
3589
3619
|
await client.execute({
|
|
3590
3620
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
@@ -3627,6 +3657,13 @@ async function ensureSchema() {
|
|
|
3627
3657
|
} catch {
|
|
3628
3658
|
}
|
|
3629
3659
|
}
|
|
3660
|
+
try {
|
|
3661
|
+
await client.execute({
|
|
3662
|
+
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3663
|
+
args: []
|
|
3664
|
+
});
|
|
3665
|
+
} catch {
|
|
3666
|
+
}
|
|
3630
3667
|
try {
|
|
3631
3668
|
await client.execute({
|
|
3632
3669
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
@@ -3687,7 +3724,7 @@ import { pathToFileURL as pathToFileURL2 } from "url";
|
|
|
3687
3724
|
import os8 from "os";
|
|
3688
3725
|
import path10 from "path";
|
|
3689
3726
|
import { jwtVerify, importSPKI } from "jose";
|
|
3690
|
-
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, PLAN_LIMITS;
|
|
3727
|
+
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE, PLAN_LIMITS;
|
|
3691
3728
|
var init_license = __esm({
|
|
3692
3729
|
"src/lib/license.ts"() {
|
|
3693
3730
|
"use strict";
|
|
@@ -3695,6 +3732,7 @@ var init_license = __esm({
|
|
|
3695
3732
|
LICENSE_PATH = path10.join(EXE_AI_DIR, "license.key");
|
|
3696
3733
|
CACHE_PATH = path10.join(EXE_AI_DIR, "license-cache.json");
|
|
3697
3734
|
DEVICE_ID_PATH = path10.join(EXE_AI_DIR, "device-id");
|
|
3735
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
3698
3736
|
PLAN_LIMITS = {
|
|
3699
3737
|
free: { devices: 1, employees: 1, memories: 5e3 },
|
|
3700
3738
|
pro: { devices: 3, employees: 5, memories: 1e5 },
|
|
@@ -4351,8 +4389,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
4351
4389
|
const complexity = input.complexity ?? "standard";
|
|
4352
4390
|
const sessionScope = earlySessionScope;
|
|
4353
4391
|
await client.execute({
|
|
4354
|
-
sql: `INSERT INTO tasks (id, title, assigned_to, assigned_by, project_name, priority, status, task_file, blocked_by, parent_task_id, reviewer, context, complexity, budget_tokens, budget_fallback_model, tokens_used, tokens_warned_at, session_scope, created_at, updated_at)
|
|
4355
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
4392
|
+
sql: `INSERT INTO tasks (id, title, assigned_to, assigned_by, project_name, priority, status, task_file, blocked_by, parent_task_id, reviewer, context, complexity, budget_tokens, budget_fallback_model, tokens_used, tokens_warned_at, session_scope, spawn_runtime, spawn_model, created_at, updated_at)
|
|
4393
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
4356
4394
|
args: [
|
|
4357
4395
|
id,
|
|
4358
4396
|
input.title,
|
|
@@ -4372,6 +4410,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
4372
4410
|
0,
|
|
4373
4411
|
null,
|
|
4374
4412
|
sessionScope,
|
|
4413
|
+
input.spawnRuntime ?? null,
|
|
4414
|
+
input.spawnModel ?? null,
|
|
4375
4415
|
now,
|
|
4376
4416
|
now
|
|
4377
4417
|
]
|
|
@@ -4428,7 +4468,9 @@ ${input.context}
|
|
|
4428
4468
|
budgetTokens: input.budgetTokens ?? null,
|
|
4429
4469
|
budgetFallbackModel: input.budgetFallbackModel ?? null,
|
|
4430
4470
|
tokensUsed: 0,
|
|
4431
|
-
tokensWarnedAt: null
|
|
4471
|
+
tokensWarnedAt: null,
|
|
4472
|
+
spawnRuntime: input.spawnRuntime ?? null,
|
|
4473
|
+
spawnModel: input.spawnModel ?? null
|
|
4432
4474
|
};
|
|
4433
4475
|
}
|
|
4434
4476
|
async function listTasks(input) {
|
|
@@ -4478,7 +4520,9 @@ async function listTasks(input) {
|
|
|
4478
4520
|
budgetTokens: r.budget_tokens !== null ? Number(r.budget_tokens) : null,
|
|
4479
4521
|
budgetFallbackModel: r.budget_fallback_model !== null ? String(r.budget_fallback_model) : null,
|
|
4480
4522
|
tokensUsed: Number(r.tokens_used ?? 0),
|
|
4481
|
-
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null
|
|
4523
|
+
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null,
|
|
4524
|
+
spawnRuntime: r.spawn_runtime !== null && r.spawn_runtime !== void 0 ? String(r.spawn_runtime) : null,
|
|
4525
|
+
spawnModel: r.spawn_model !== null && r.spawn_model !== void 0 ? String(r.spawn_model) : null
|
|
4482
4526
|
}));
|
|
4483
4527
|
}
|
|
4484
4528
|
function isTmuxSessionAlive(identifier) {
|
|
@@ -5846,6 +5890,8 @@ async function updateTask(input) {
|
|
|
5846
5890
|
budgetFallbackModel: row.budget_fallback_model !== void 0 && row.budget_fallback_model !== null ? String(row.budget_fallback_model) : null,
|
|
5847
5891
|
tokensUsed: Number(row.tokens_used ?? 0),
|
|
5848
5892
|
tokensWarnedAt: row.tokens_warned_at !== void 0 && row.tokens_warned_at !== null ? Number(row.tokens_warned_at) : null,
|
|
5893
|
+
spawnRuntime: row.spawn_runtime !== void 0 && row.spawn_runtime !== null ? String(row.spawn_runtime) : null,
|
|
5894
|
+
spawnModel: row.spawn_model !== void 0 && row.spawn_model !== null ? String(row.spawn_model) : null,
|
|
5849
5895
|
nextTask
|
|
5850
5896
|
};
|
|
5851
5897
|
}
|
|
@@ -6341,6 +6387,7 @@ function resolveExeSession() {
|
|
|
6341
6387
|
const mySession = getMySession();
|
|
6342
6388
|
if (!mySession) return null;
|
|
6343
6389
|
const fromSessionName = extractRootExe(mySession);
|
|
6390
|
+
let candidate = null;
|
|
6344
6391
|
try {
|
|
6345
6392
|
const key = getSessionKey();
|
|
6346
6393
|
const parentExe = getParentExe(key);
|
|
@@ -6351,13 +6398,47 @@ function resolveExeSession() {
|
|
|
6351
6398
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
6352
6399
|
`
|
|
6353
6400
|
);
|
|
6354
|
-
|
|
6401
|
+
candidate = fromSessionName;
|
|
6402
|
+
} else {
|
|
6403
|
+
candidate = fromCache;
|
|
6355
6404
|
}
|
|
6356
|
-
return fromCache;
|
|
6357
6405
|
}
|
|
6358
6406
|
} catch {
|
|
6359
6407
|
}
|
|
6360
|
-
|
|
6408
|
+
if (!candidate) {
|
|
6409
|
+
candidate = fromSessionName ?? mySession;
|
|
6410
|
+
}
|
|
6411
|
+
if (candidate && isRootSession(candidate)) {
|
|
6412
|
+
try {
|
|
6413
|
+
const transport = getTransport();
|
|
6414
|
+
const liveSessions = transport.listSessions();
|
|
6415
|
+
if (!liveSessions.includes(candidate)) {
|
|
6416
|
+
const liveRoots = liveSessions.filter((s) => isRootSession(s));
|
|
6417
|
+
if (liveRoots.length === 1) {
|
|
6418
|
+
process.stderr.write(
|
|
6419
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. Using live coordinator "${liveRoots[0]}".
|
|
6420
|
+
`
|
|
6421
|
+
);
|
|
6422
|
+
return liveRoots[0];
|
|
6423
|
+
} else if (liveRoots.length > 1) {
|
|
6424
|
+
const base = candidate.replace(/\d+$/, "");
|
|
6425
|
+
const match = liveRoots.find((s) => s.startsWith(base));
|
|
6426
|
+
const chosen = match ?? liveRoots[0];
|
|
6427
|
+
process.stderr.write(
|
|
6428
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. ${liveRoots.length} live roots found, using "${chosen}".
|
|
6429
|
+
`
|
|
6430
|
+
);
|
|
6431
|
+
return chosen;
|
|
6432
|
+
}
|
|
6433
|
+
process.stderr.write(
|
|
6434
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead and no live coordinator found.
|
|
6435
|
+
`
|
|
6436
|
+
);
|
|
6437
|
+
}
|
|
6438
|
+
} catch {
|
|
6439
|
+
}
|
|
6440
|
+
}
|
|
6441
|
+
return candidate;
|
|
6361
6442
|
}
|
|
6362
6443
|
function isEmployeeAlive(sessionName) {
|
|
6363
6444
|
return getTransport().isAlive(sessionName);
|
|
@@ -6759,7 +6840,12 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
6759
6840
|
}
|
|
6760
6841
|
const spawnCwd = opts?.cwd ?? projectDir;
|
|
6761
6842
|
const useExeAgent = !!(opts?.model && opts?.provider);
|
|
6762
|
-
const
|
|
6843
|
+
const baseRtConfig = getAgentRuntime(employeeName);
|
|
6844
|
+
const agentRtConfig = {
|
|
6845
|
+
...baseRtConfig,
|
|
6846
|
+
...opts?.runtimeOverride ? { runtime: opts.runtimeOverride } : {},
|
|
6847
|
+
...opts?.modelOverride ? { model: opts.modelOverride } : {}
|
|
6848
|
+
};
|
|
6763
6849
|
const useCodex = !useExeAgent && agentRtConfig.runtime === "codex";
|
|
6764
6850
|
const useOpencode = !useExeAgent && !useCodex && agentRtConfig.runtime === "opencode";
|
|
6765
6851
|
const ccProvider = useExeAgent || useCodex || useOpencode ? DEFAULT_PROVIDER : detectActiveProvider();
|
|
@@ -8019,6 +8105,20 @@ var init_platform_procedures = __esm({
|
|
|
8019
8105
|
priority: "p1",
|
|
8020
8106
|
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."
|
|
8021
8107
|
},
|
|
8108
|
+
// --- Tool guidance ---
|
|
8109
|
+
{
|
|
8110
|
+
title: "How to use company_actions \u2014 execute business actions through gateway connectors",
|
|
8111
|
+
domain: "tools",
|
|
8112
|
+
priority: "p2",
|
|
8113
|
+
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."
|
|
8114
|
+
},
|
|
8115
|
+
// --- Release awareness ---
|
|
8116
|
+
{
|
|
8117
|
+
title: "What's New check \u2014 surface new features after update",
|
|
8118
|
+
domain: "support",
|
|
8119
|
+
priority: "p1",
|
|
8120
|
+
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."
|
|
8121
|
+
},
|
|
8022
8122
|
// --- Platform vs Customer ownership ---
|
|
8023
8123
|
{
|
|
8024
8124
|
title: "What the platform provides vs what you customize",
|
|
@@ -8107,13 +8207,13 @@ var init_platform_procedures = __esm({
|
|
|
8107
8207
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
8108
8208
|
domain: "tool-use",
|
|
8109
8209
|
priority: "p1",
|
|
8110
|
-
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.`
|
|
8210
|
+
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.`
|
|
8111
8211
|
},
|
|
8112
8212
|
{
|
|
8113
8213
|
title: "MCP tools \u2014 task orchestration",
|
|
8114
8214
|
domain: "tool-use",
|
|
8115
8215
|
priority: "p1",
|
|
8116
|
-
content:
|
|
8216
|
+
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.`
|
|
8117
8217
|
},
|
|
8118
8218
|
{
|
|
8119
8219
|
title: "MCP tools \u2014 knowledge graph (GraphRAG)",
|
|
@@ -8143,7 +8243,7 @@ var init_platform_procedures = __esm({
|
|
|
8143
8243
|
title: "MCP tools \u2014 admin, config, and operations",
|
|
8144
8244
|
domain: "tool-use",
|
|
8145
8245
|
priority: "p1",
|
|
8146
|
-
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.'
|
|
8246
|
+
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.'
|
|
8147
8247
|
}
|
|
8148
8248
|
];
|
|
8149
8249
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -8827,6 +8927,8 @@ async function writeMemory(record) {
|
|
|
8827
8927
|
source_type: record.source_type ?? null,
|
|
8828
8928
|
tier: record.tier ?? classifyTier(record),
|
|
8829
8929
|
supersedes_id: record.supersedes_id ?? null,
|
|
8930
|
+
valid_from: record.valid_from ?? record.timestamp,
|
|
8931
|
+
invalid_at: record.invalid_at ?? null,
|
|
8830
8932
|
draft: record.draft ? 1 : 0,
|
|
8831
8933
|
memory_type: memoryType,
|
|
8832
8934
|
trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
|
|
@@ -8845,7 +8947,8 @@ async function writeMemory(record) {
|
|
|
8845
8947
|
token_cost: record.token_cost ?? null,
|
|
8846
8948
|
audience: record.audience ?? null,
|
|
8847
8949
|
language_type: record.language_type ?? inferLanguageType(record),
|
|
8848
|
-
parent_memory_id: record.parent_memory_id ?? null
|
|
8950
|
+
parent_memory_id: record.parent_memory_id ?? null,
|
|
8951
|
+
procedure_for: record.procedure_for ?? null
|
|
8849
8952
|
};
|
|
8850
8953
|
_pendingRecords.push(dbRow);
|
|
8851
8954
|
orgBus.emit({
|
|
@@ -8900,6 +9003,8 @@ async function flushBatch() {
|
|
|
8900
9003
|
const sourceType = row.source_type ?? null;
|
|
8901
9004
|
const tier = row.tier ?? 3;
|
|
8902
9005
|
const supersedesId = row.supersedes_id ?? null;
|
|
9006
|
+
const validFrom = row.valid_from ?? row.timestamp;
|
|
9007
|
+
const invalidAt = row.invalid_at ?? null;
|
|
8903
9008
|
const draft = row.draft ? 1 : 0;
|
|
8904
9009
|
const memoryType = row.memory_type ?? "raw";
|
|
8905
9010
|
const trajectory = row.trajectory ?? null;
|
|
@@ -8919,15 +9024,16 @@ async function flushBatch() {
|
|
|
8919
9024
|
const audience = row.audience ?? null;
|
|
8920
9025
|
const languageType = row.language_type ?? null;
|
|
8921
9026
|
const parentMemoryId = row.parent_memory_id ?? null;
|
|
9027
|
+
const procedureFor = row.procedure_for ?? null;
|
|
8922
9028
|
const cols = `id, agent_id, agent_role, session_id, timestamp,
|
|
8923
9029
|
tool_name, project_name,
|
|
8924
9030
|
has_error, raw_text, vector, version, task_id, importance, status,
|
|
8925
9031
|
confidence, last_accessed,
|
|
8926
9032
|
workspace_id, document_id, user_id, char_offset, page_number,
|
|
8927
|
-
source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
|
|
9033
|
+
source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
|
|
8928
9034
|
intent, outcome, domain, referenced_entities, retrieval_count,
|
|
8929
9035
|
chain_position, review_status, context_window_pct, file_paths, commit_hash,
|
|
8930
|
-
duration_ms, token_cost, audience, language_type, parent_memory_id`;
|
|
9036
|
+
duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for`;
|
|
8931
9037
|
const metaArgs = [
|
|
8932
9038
|
intent,
|
|
8933
9039
|
outcome,
|
|
@@ -8943,7 +9049,8 @@ async function flushBatch() {
|
|
|
8943
9049
|
tokenCost,
|
|
8944
9050
|
audience,
|
|
8945
9051
|
languageType,
|
|
8946
|
-
parentMemoryId
|
|
9052
|
+
parentMemoryId,
|
|
9053
|
+
procedureFor
|
|
8947
9054
|
];
|
|
8948
9055
|
const baseArgs = [
|
|
8949
9056
|
row.id,
|
|
@@ -8972,6 +9079,8 @@ async function flushBatch() {
|
|
|
8972
9079
|
sourceType,
|
|
8973
9080
|
tier,
|
|
8974
9081
|
supersedesId,
|
|
9082
|
+
validFrom,
|
|
9083
|
+
invalidAt,
|
|
8975
9084
|
draft,
|
|
8976
9085
|
memoryType,
|
|
8977
9086
|
trajectory,
|
|
@@ -8979,8 +9088,8 @@ async function flushBatch() {
|
|
|
8979
9088
|
];
|
|
8980
9089
|
return {
|
|
8981
9090
|
sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
|
|
8982
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
8983
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
9091
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
9092
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
8984
9093
|
args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
|
|
8985
9094
|
};
|
|
8986
9095
|
};
|
|
@@ -9096,6 +9205,12 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
9096
9205
|
AND vector IS NOT NULL${statusFilter}${draftFilter}
|
|
9097
9206
|
AND COALESCE(confidence, 0.7) >= 0.3`;
|
|
9098
9207
|
const args = [agentId];
|
|
9208
|
+
if (options?.asOf) {
|
|
9209
|
+
sql += ` AND (valid_from IS NULL OR valid_from <= ?) AND (invalid_at IS NULL OR invalid_at > ?)`;
|
|
9210
|
+
args.push(options.asOf, options.asOf);
|
|
9211
|
+
} else {
|
|
9212
|
+
sql += ` AND invalid_at IS NULL`;
|
|
9213
|
+
}
|
|
9099
9214
|
const scope = buildWikiScopeFilter(options, "");
|
|
9100
9215
|
sql += scope.clause;
|
|
9101
9216
|
args.push(...scope.args);
|
package/dist/tui/App.js
CHANGED
|
@@ -3586,6 +3586,20 @@ async function ensureSchema() {
|
|
|
3586
3586
|
});
|
|
3587
3587
|
} catch {
|
|
3588
3588
|
}
|
|
3589
|
+
try {
|
|
3590
|
+
await client.execute({
|
|
3591
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
3592
|
+
args: []
|
|
3593
|
+
});
|
|
3594
|
+
} catch {
|
|
3595
|
+
}
|
|
3596
|
+
try {
|
|
3597
|
+
await client.execute({
|
|
3598
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
3599
|
+
args: []
|
|
3600
|
+
});
|
|
3601
|
+
} catch {
|
|
3602
|
+
}
|
|
3589
3603
|
await client.executeMultiple(`
|
|
3590
3604
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
3591
3605
|
content_text,
|
|
@@ -3837,6 +3851,22 @@ async function ensureSchema() {
|
|
|
3837
3851
|
);
|
|
3838
3852
|
} catch {
|
|
3839
3853
|
}
|
|
3854
|
+
for (const col of [
|
|
3855
|
+
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
3856
|
+
"ALTER TABLE memories ADD COLUMN invalid_at TEXT"
|
|
3857
|
+
]) {
|
|
3858
|
+
try {
|
|
3859
|
+
await client.execute(col);
|
|
3860
|
+
} catch {
|
|
3861
|
+
}
|
|
3862
|
+
}
|
|
3863
|
+
try {
|
|
3864
|
+
await client.execute({
|
|
3865
|
+
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3866
|
+
args: []
|
|
3867
|
+
});
|
|
3868
|
+
} catch {
|
|
3869
|
+
}
|
|
3840
3870
|
try {
|
|
3841
3871
|
await client.execute({
|
|
3842
3872
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
@@ -3879,6 +3909,13 @@ async function ensureSchema() {
|
|
|
3879
3909
|
} catch {
|
|
3880
3910
|
}
|
|
3881
3911
|
}
|
|
3912
|
+
try {
|
|
3913
|
+
await client.execute({
|
|
3914
|
+
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3915
|
+
args: []
|
|
3916
|
+
});
|
|
3917
|
+
} catch {
|
|
3918
|
+
}
|
|
3882
3919
|
try {
|
|
3883
3920
|
await client.execute({
|
|
3884
3921
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
@@ -4368,7 +4405,7 @@ var init_license = __esm({
|
|
|
4368
4405
|
LICENSE_PATH = path9.join(EXE_AI_DIR, "license.key");
|
|
4369
4406
|
CACHE_PATH = path9.join(EXE_AI_DIR, "license-cache.json");
|
|
4370
4407
|
DEVICE_ID_PATH = path9.join(EXE_AI_DIR, "device-id");
|
|
4371
|
-
API_BASE = "https://askexe.com/cloud";
|
|
4408
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
4372
4409
|
RETRY_DELAY_MS = 500;
|
|
4373
4410
|
LICENSE_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
|
|
4374
4411
|
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeHztAMOpR/ZMh+rWuOASjEZ54CGY
|
|
@@ -5021,8 +5058,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
5021
5058
|
const complexity = input.complexity ?? "standard";
|
|
5022
5059
|
const sessionScope = earlySessionScope;
|
|
5023
5060
|
await client.execute({
|
|
5024
|
-
sql: `INSERT INTO tasks (id, title, assigned_to, assigned_by, project_name, priority, status, task_file, blocked_by, parent_task_id, reviewer, context, complexity, budget_tokens, budget_fallback_model, tokens_used, tokens_warned_at, session_scope, created_at, updated_at)
|
|
5025
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5061
|
+
sql: `INSERT INTO tasks (id, title, assigned_to, assigned_by, project_name, priority, status, task_file, blocked_by, parent_task_id, reviewer, context, complexity, budget_tokens, budget_fallback_model, tokens_used, tokens_warned_at, session_scope, spawn_runtime, spawn_model, created_at, updated_at)
|
|
5062
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
5026
5063
|
args: [
|
|
5027
5064
|
id,
|
|
5028
5065
|
input.title,
|
|
@@ -5042,6 +5079,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
5042
5079
|
0,
|
|
5043
5080
|
null,
|
|
5044
5081
|
sessionScope,
|
|
5082
|
+
input.spawnRuntime ?? null,
|
|
5083
|
+
input.spawnModel ?? null,
|
|
5045
5084
|
now,
|
|
5046
5085
|
now
|
|
5047
5086
|
]
|
|
@@ -5098,7 +5137,9 @@ ${input.context}
|
|
|
5098
5137
|
budgetTokens: input.budgetTokens ?? null,
|
|
5099
5138
|
budgetFallbackModel: input.budgetFallbackModel ?? null,
|
|
5100
5139
|
tokensUsed: 0,
|
|
5101
|
-
tokensWarnedAt: null
|
|
5140
|
+
tokensWarnedAt: null,
|
|
5141
|
+
spawnRuntime: input.spawnRuntime ?? null,
|
|
5142
|
+
spawnModel: input.spawnModel ?? null
|
|
5102
5143
|
};
|
|
5103
5144
|
}
|
|
5104
5145
|
async function listTasks(input) {
|
|
@@ -5148,7 +5189,9 @@ async function listTasks(input) {
|
|
|
5148
5189
|
budgetTokens: r.budget_tokens !== null ? Number(r.budget_tokens) : null,
|
|
5149
5190
|
budgetFallbackModel: r.budget_fallback_model !== null ? String(r.budget_fallback_model) : null,
|
|
5150
5191
|
tokensUsed: Number(r.tokens_used ?? 0),
|
|
5151
|
-
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null
|
|
5192
|
+
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null,
|
|
5193
|
+
spawnRuntime: r.spawn_runtime !== null && r.spawn_runtime !== void 0 ? String(r.spawn_runtime) : null,
|
|
5194
|
+
spawnModel: r.spawn_model !== null && r.spawn_model !== void 0 ? String(r.spawn_model) : null
|
|
5152
5195
|
}));
|
|
5153
5196
|
}
|
|
5154
5197
|
function isTmuxSessionAlive(identifier) {
|
|
@@ -6445,6 +6488,8 @@ async function updateTask(input) {
|
|
|
6445
6488
|
budgetFallbackModel: row.budget_fallback_model !== void 0 && row.budget_fallback_model !== null ? String(row.budget_fallback_model) : null,
|
|
6446
6489
|
tokensUsed: Number(row.tokens_used ?? 0),
|
|
6447
6490
|
tokensWarnedAt: row.tokens_warned_at !== void 0 && row.tokens_warned_at !== null ? Number(row.tokens_warned_at) : null,
|
|
6491
|
+
spawnRuntime: row.spawn_runtime !== void 0 && row.spawn_runtime !== null ? String(row.spawn_runtime) : null,
|
|
6492
|
+
spawnModel: row.spawn_model !== void 0 && row.spawn_model !== null ? String(row.spawn_model) : null,
|
|
6448
6493
|
nextTask
|
|
6449
6494
|
};
|
|
6450
6495
|
}
|
|
@@ -6940,6 +6985,7 @@ function resolveExeSession() {
|
|
|
6940
6985
|
const mySession = getMySession();
|
|
6941
6986
|
if (!mySession) return null;
|
|
6942
6987
|
const fromSessionName = extractRootExe(mySession);
|
|
6988
|
+
let candidate = null;
|
|
6943
6989
|
try {
|
|
6944
6990
|
const key = getSessionKey();
|
|
6945
6991
|
const parentExe = getParentExe(key);
|
|
@@ -6950,13 +6996,47 @@ function resolveExeSession() {
|
|
|
6950
6996
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
6951
6997
|
`
|
|
6952
6998
|
);
|
|
6953
|
-
|
|
6999
|
+
candidate = fromSessionName;
|
|
7000
|
+
} else {
|
|
7001
|
+
candidate = fromCache;
|
|
6954
7002
|
}
|
|
6955
|
-
return fromCache;
|
|
6956
7003
|
}
|
|
6957
7004
|
} catch {
|
|
6958
7005
|
}
|
|
6959
|
-
|
|
7006
|
+
if (!candidate) {
|
|
7007
|
+
candidate = fromSessionName ?? mySession;
|
|
7008
|
+
}
|
|
7009
|
+
if (candidate && isRootSession(candidate)) {
|
|
7010
|
+
try {
|
|
7011
|
+
const transport = getTransport();
|
|
7012
|
+
const liveSessions = transport.listSessions();
|
|
7013
|
+
if (!liveSessions.includes(candidate)) {
|
|
7014
|
+
const liveRoots = liveSessions.filter((s) => isRootSession(s));
|
|
7015
|
+
if (liveRoots.length === 1) {
|
|
7016
|
+
process.stderr.write(
|
|
7017
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. Using live coordinator "${liveRoots[0]}".
|
|
7018
|
+
`
|
|
7019
|
+
);
|
|
7020
|
+
return liveRoots[0];
|
|
7021
|
+
} else if (liveRoots.length > 1) {
|
|
7022
|
+
const base = candidate.replace(/\d+$/, "");
|
|
7023
|
+
const match = liveRoots.find((s) => s.startsWith(base));
|
|
7024
|
+
const chosen = match ?? liveRoots[0];
|
|
7025
|
+
process.stderr.write(
|
|
7026
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. ${liveRoots.length} live roots found, using "${chosen}".
|
|
7027
|
+
`
|
|
7028
|
+
);
|
|
7029
|
+
return chosen;
|
|
7030
|
+
}
|
|
7031
|
+
process.stderr.write(
|
|
7032
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead and no live coordinator found.
|
|
7033
|
+
`
|
|
7034
|
+
);
|
|
7035
|
+
}
|
|
7036
|
+
} catch {
|
|
7037
|
+
}
|
|
7038
|
+
}
|
|
7039
|
+
return candidate;
|
|
6960
7040
|
}
|
|
6961
7041
|
function isEmployeeAlive(sessionName) {
|
|
6962
7042
|
return getTransport().isAlive(sessionName);
|
|
@@ -7358,7 +7438,12 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
7358
7438
|
}
|
|
7359
7439
|
const spawnCwd = opts?.cwd ?? projectDir;
|
|
7360
7440
|
const useExeAgent = !!(opts?.model && opts?.provider);
|
|
7361
|
-
const
|
|
7441
|
+
const baseRtConfig = getAgentRuntime(employeeName);
|
|
7442
|
+
const agentRtConfig = {
|
|
7443
|
+
...baseRtConfig,
|
|
7444
|
+
...opts?.runtimeOverride ? { runtime: opts.runtimeOverride } : {},
|
|
7445
|
+
...opts?.modelOverride ? { model: opts.modelOverride } : {}
|
|
7446
|
+
};
|
|
7362
7447
|
const useCodex = !useExeAgent && agentRtConfig.runtime === "codex";
|
|
7363
7448
|
const useOpencode = !useExeAgent && !useCodex && agentRtConfig.runtime === "opencode";
|
|
7364
7449
|
const ccProvider = useExeAgent || useCodex || useOpencode ? DEFAULT_PROVIDER : detectActiveProvider();
|
|
@@ -8991,6 +9076,20 @@ var init_platform_procedures = __esm({
|
|
|
8991
9076
|
priority: "p1",
|
|
8992
9077
|
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."
|
|
8993
9078
|
},
|
|
9079
|
+
// --- Tool guidance ---
|
|
9080
|
+
{
|
|
9081
|
+
title: "How to use company_actions \u2014 execute business actions through gateway connectors",
|
|
9082
|
+
domain: "tools",
|
|
9083
|
+
priority: "p2",
|
|
9084
|
+
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."
|
|
9085
|
+
},
|
|
9086
|
+
// --- Release awareness ---
|
|
9087
|
+
{
|
|
9088
|
+
title: "What's New check \u2014 surface new features after update",
|
|
9089
|
+
domain: "support",
|
|
9090
|
+
priority: "p1",
|
|
9091
|
+
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."
|
|
9092
|
+
},
|
|
8994
9093
|
// --- Platform vs Customer ownership ---
|
|
8995
9094
|
{
|
|
8996
9095
|
title: "What the platform provides vs what you customize",
|
|
@@ -9079,13 +9178,13 @@ var init_platform_procedures = __esm({
|
|
|
9079
9178
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
9080
9179
|
domain: "tool-use",
|
|
9081
9180
|
priority: "p1",
|
|
9082
|
-
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.`
|
|
9181
|
+
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.`
|
|
9083
9182
|
},
|
|
9084
9183
|
{
|
|
9085
9184
|
title: "MCP tools \u2014 task orchestration",
|
|
9086
9185
|
domain: "tool-use",
|
|
9087
9186
|
priority: "p1",
|
|
9088
|
-
content:
|
|
9187
|
+
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.`
|
|
9089
9188
|
},
|
|
9090
9189
|
{
|
|
9091
9190
|
title: "MCP tools \u2014 knowledge graph (GraphRAG)",
|
|
@@ -9115,7 +9214,7 @@ var init_platform_procedures = __esm({
|
|
|
9115
9214
|
title: "MCP tools \u2014 admin, config, and operations",
|
|
9116
9215
|
domain: "tool-use",
|
|
9117
9216
|
priority: "p1",
|
|
9118
|
-
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.'
|
|
9217
|
+
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.'
|
|
9119
9218
|
}
|
|
9120
9219
|
];
|
|
9121
9220
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -12936,6 +13035,8 @@ async function writeMemory(record) {
|
|
|
12936
13035
|
source_type: record.source_type ?? null,
|
|
12937
13036
|
tier: record.tier ?? classifyTier(record),
|
|
12938
13037
|
supersedes_id: record.supersedes_id ?? null,
|
|
13038
|
+
valid_from: record.valid_from ?? record.timestamp,
|
|
13039
|
+
invalid_at: record.invalid_at ?? null,
|
|
12939
13040
|
draft: record.draft ? 1 : 0,
|
|
12940
13041
|
memory_type: memoryType,
|
|
12941
13042
|
trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
|
|
@@ -12954,7 +13055,8 @@ async function writeMemory(record) {
|
|
|
12954
13055
|
token_cost: record.token_cost ?? null,
|
|
12955
13056
|
audience: record.audience ?? null,
|
|
12956
13057
|
language_type: record.language_type ?? inferLanguageType(record),
|
|
12957
|
-
parent_memory_id: record.parent_memory_id ?? null
|
|
13058
|
+
parent_memory_id: record.parent_memory_id ?? null,
|
|
13059
|
+
procedure_for: record.procedure_for ?? null
|
|
12958
13060
|
};
|
|
12959
13061
|
_pendingRecords.push(dbRow);
|
|
12960
13062
|
orgBus.emit({
|
|
@@ -13009,6 +13111,8 @@ async function flushBatch() {
|
|
|
13009
13111
|
const sourceType = row.source_type ?? null;
|
|
13010
13112
|
const tier = row.tier ?? 3;
|
|
13011
13113
|
const supersedesId = row.supersedes_id ?? null;
|
|
13114
|
+
const validFrom = row.valid_from ?? row.timestamp;
|
|
13115
|
+
const invalidAt = row.invalid_at ?? null;
|
|
13012
13116
|
const draft = row.draft ? 1 : 0;
|
|
13013
13117
|
const memoryType = row.memory_type ?? "raw";
|
|
13014
13118
|
const trajectory = row.trajectory ?? null;
|
|
@@ -13028,15 +13132,16 @@ async function flushBatch() {
|
|
|
13028
13132
|
const audience = row.audience ?? null;
|
|
13029
13133
|
const languageType = row.language_type ?? null;
|
|
13030
13134
|
const parentMemoryId = row.parent_memory_id ?? null;
|
|
13135
|
+
const procedureFor = row.procedure_for ?? null;
|
|
13031
13136
|
const cols = `id, agent_id, agent_role, session_id, timestamp,
|
|
13032
13137
|
tool_name, project_name,
|
|
13033
13138
|
has_error, raw_text, vector, version, task_id, importance, status,
|
|
13034
13139
|
confidence, last_accessed,
|
|
13035
13140
|
workspace_id, document_id, user_id, char_offset, page_number,
|
|
13036
|
-
source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
|
|
13141
|
+
source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
|
|
13037
13142
|
intent, outcome, domain, referenced_entities, retrieval_count,
|
|
13038
13143
|
chain_position, review_status, context_window_pct, file_paths, commit_hash,
|
|
13039
|
-
duration_ms, token_cost, audience, language_type, parent_memory_id`;
|
|
13144
|
+
duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for`;
|
|
13040
13145
|
const metaArgs = [
|
|
13041
13146
|
intent,
|
|
13042
13147
|
outcome,
|
|
@@ -13052,7 +13157,8 @@ async function flushBatch() {
|
|
|
13052
13157
|
tokenCost,
|
|
13053
13158
|
audience,
|
|
13054
13159
|
languageType,
|
|
13055
|
-
parentMemoryId
|
|
13160
|
+
parentMemoryId,
|
|
13161
|
+
procedureFor
|
|
13056
13162
|
];
|
|
13057
13163
|
const baseArgs = [
|
|
13058
13164
|
row.id,
|
|
@@ -13081,6 +13187,8 @@ async function flushBatch() {
|
|
|
13081
13187
|
sourceType,
|
|
13082
13188
|
tier,
|
|
13083
13189
|
supersedesId,
|
|
13190
|
+
validFrom,
|
|
13191
|
+
invalidAt,
|
|
13084
13192
|
draft,
|
|
13085
13193
|
memoryType,
|
|
13086
13194
|
trajectory,
|
|
@@ -13088,8 +13196,8 @@ async function flushBatch() {
|
|
|
13088
13196
|
];
|
|
13089
13197
|
return {
|
|
13090
13198
|
sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
|
|
13091
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
13092
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
13199
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
13200
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
13093
13201
|
args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
|
|
13094
13202
|
};
|
|
13095
13203
|
};
|
|
@@ -13205,6 +13313,12 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
13205
13313
|
AND vector IS NOT NULL${statusFilter}${draftFilter}
|
|
13206
13314
|
AND COALESCE(confidence, 0.7) >= 0.3`;
|
|
13207
13315
|
const args = [agentId];
|
|
13316
|
+
if (options?.asOf) {
|
|
13317
|
+
sql += ` AND (valid_from IS NULL OR valid_from <= ?) AND (invalid_at IS NULL OR invalid_at > ?)`;
|
|
13318
|
+
args.push(options.asOf, options.asOf);
|
|
13319
|
+
} else {
|
|
13320
|
+
sql += ` AND invalid_at IS NULL`;
|
|
13321
|
+
}
|
|
13208
13322
|
const scope = buildWikiScopeFilter(options, "");
|
|
13209
13323
|
sql += scope.clause;
|
|
13210
13324
|
args.push(...scope.args);
|