@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
|
@@ -3353,6 +3353,20 @@ async function ensureSchema() {
|
|
|
3353
3353
|
});
|
|
3354
3354
|
} catch {
|
|
3355
3355
|
}
|
|
3356
|
+
try {
|
|
3357
|
+
await client.execute({
|
|
3358
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
3359
|
+
args: []
|
|
3360
|
+
});
|
|
3361
|
+
} catch {
|
|
3362
|
+
}
|
|
3363
|
+
try {
|
|
3364
|
+
await client.execute({
|
|
3365
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
3366
|
+
args: []
|
|
3367
|
+
});
|
|
3368
|
+
} catch {
|
|
3369
|
+
}
|
|
3356
3370
|
await client.executeMultiple(`
|
|
3357
3371
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
3358
3372
|
content_text,
|
|
@@ -3604,6 +3618,22 @@ async function ensureSchema() {
|
|
|
3604
3618
|
);
|
|
3605
3619
|
} catch {
|
|
3606
3620
|
}
|
|
3621
|
+
for (const col of [
|
|
3622
|
+
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
3623
|
+
"ALTER TABLE memories ADD COLUMN invalid_at TEXT"
|
|
3624
|
+
]) {
|
|
3625
|
+
try {
|
|
3626
|
+
await client.execute(col);
|
|
3627
|
+
} catch {
|
|
3628
|
+
}
|
|
3629
|
+
}
|
|
3630
|
+
try {
|
|
3631
|
+
await client.execute({
|
|
3632
|
+
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3633
|
+
args: []
|
|
3634
|
+
});
|
|
3635
|
+
} catch {
|
|
3636
|
+
}
|
|
3607
3637
|
try {
|
|
3608
3638
|
await client.execute({
|
|
3609
3639
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
@@ -3646,6 +3676,13 @@ async function ensureSchema() {
|
|
|
3646
3676
|
} catch {
|
|
3647
3677
|
}
|
|
3648
3678
|
}
|
|
3679
|
+
try {
|
|
3680
|
+
await client.execute({
|
|
3681
|
+
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3682
|
+
args: []
|
|
3683
|
+
});
|
|
3684
|
+
} catch {
|
|
3685
|
+
}
|
|
3649
3686
|
try {
|
|
3650
3687
|
await client.execute({
|
|
3651
3688
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
@@ -3706,7 +3743,7 @@ import { pathToFileURL as pathToFileURL2 } from "url";
|
|
|
3706
3743
|
import os7 from "os";
|
|
3707
3744
|
import path10 from "path";
|
|
3708
3745
|
import { jwtVerify, importSPKI } from "jose";
|
|
3709
|
-
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, PLAN_LIMITS;
|
|
3746
|
+
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE, PLAN_LIMITS;
|
|
3710
3747
|
var init_license = __esm({
|
|
3711
3748
|
"src/lib/license.ts"() {
|
|
3712
3749
|
"use strict";
|
|
@@ -3714,6 +3751,7 @@ var init_license = __esm({
|
|
|
3714
3751
|
LICENSE_PATH = path10.join(EXE_AI_DIR, "license.key");
|
|
3715
3752
|
CACHE_PATH = path10.join(EXE_AI_DIR, "license-cache.json");
|
|
3716
3753
|
DEVICE_ID_PATH = path10.join(EXE_AI_DIR, "device-id");
|
|
3754
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
3717
3755
|
PLAN_LIMITS = {
|
|
3718
3756
|
free: { devices: 1, employees: 1, memories: 5e3 },
|
|
3719
3757
|
pro: { devices: 3, employees: 5, memories: 1e5 },
|
|
@@ -4331,8 +4369,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
4331
4369
|
const complexity = input2.complexity ?? "standard";
|
|
4332
4370
|
const sessionScope = earlySessionScope;
|
|
4333
4371
|
await client.execute({
|
|
4334
|
-
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)
|
|
4335
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
4372
|
+
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)
|
|
4373
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
4336
4374
|
args: [
|
|
4337
4375
|
id,
|
|
4338
4376
|
input2.title,
|
|
@@ -4352,6 +4390,8 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
4352
4390
|
0,
|
|
4353
4391
|
null,
|
|
4354
4392
|
sessionScope,
|
|
4393
|
+
input2.spawnRuntime ?? null,
|
|
4394
|
+
input2.spawnModel ?? null,
|
|
4355
4395
|
now,
|
|
4356
4396
|
now
|
|
4357
4397
|
]
|
|
@@ -4408,7 +4448,9 @@ ${input2.context}
|
|
|
4408
4448
|
budgetTokens: input2.budgetTokens ?? null,
|
|
4409
4449
|
budgetFallbackModel: input2.budgetFallbackModel ?? null,
|
|
4410
4450
|
tokensUsed: 0,
|
|
4411
|
-
tokensWarnedAt: null
|
|
4451
|
+
tokensWarnedAt: null,
|
|
4452
|
+
spawnRuntime: input2.spawnRuntime ?? null,
|
|
4453
|
+
spawnModel: input2.spawnModel ?? null
|
|
4412
4454
|
};
|
|
4413
4455
|
}
|
|
4414
4456
|
async function listTasks(input2) {
|
|
@@ -4458,7 +4500,9 @@ async function listTasks(input2) {
|
|
|
4458
4500
|
budgetTokens: r.budget_tokens !== null ? Number(r.budget_tokens) : null,
|
|
4459
4501
|
budgetFallbackModel: r.budget_fallback_model !== null ? String(r.budget_fallback_model) : null,
|
|
4460
4502
|
tokensUsed: Number(r.tokens_used ?? 0),
|
|
4461
|
-
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null
|
|
4503
|
+
tokensWarnedAt: r.tokens_warned_at !== null ? Number(r.tokens_warned_at) : null,
|
|
4504
|
+
spawnRuntime: r.spawn_runtime !== null && r.spawn_runtime !== void 0 ? String(r.spawn_runtime) : null,
|
|
4505
|
+
spawnModel: r.spawn_model !== null && r.spawn_model !== void 0 ? String(r.spawn_model) : null
|
|
4462
4506
|
}));
|
|
4463
4507
|
}
|
|
4464
4508
|
function isTmuxSessionAlive(identifier) {
|
|
@@ -5755,6 +5799,8 @@ async function updateTask(input2) {
|
|
|
5755
5799
|
budgetFallbackModel: row.budget_fallback_model !== void 0 && row.budget_fallback_model !== null ? String(row.budget_fallback_model) : null,
|
|
5756
5800
|
tokensUsed: Number(row.tokens_used ?? 0),
|
|
5757
5801
|
tokensWarnedAt: row.tokens_warned_at !== void 0 && row.tokens_warned_at !== null ? Number(row.tokens_warned_at) : null,
|
|
5802
|
+
spawnRuntime: row.spawn_runtime !== void 0 && row.spawn_runtime !== null ? String(row.spawn_runtime) : null,
|
|
5803
|
+
spawnModel: row.spawn_model !== void 0 && row.spawn_model !== null ? String(row.spawn_model) : null,
|
|
5758
5804
|
nextTask
|
|
5759
5805
|
};
|
|
5760
5806
|
}
|
|
@@ -6247,9 +6293,13 @@ function getDispatchedBy(sessionKey) {
|
|
|
6247
6293
|
}
|
|
6248
6294
|
}
|
|
6249
6295
|
function resolveExeSession() {
|
|
6296
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
6297
|
+
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
6298
|
+
}
|
|
6250
6299
|
const mySession = getMySession();
|
|
6251
6300
|
if (!mySession) return null;
|
|
6252
6301
|
const fromSessionName = extractRootExe(mySession);
|
|
6302
|
+
let candidate = null;
|
|
6253
6303
|
try {
|
|
6254
6304
|
const key = getSessionKey();
|
|
6255
6305
|
const parentExe = getParentExe(key);
|
|
@@ -6260,13 +6310,47 @@ function resolveExeSession() {
|
|
|
6260
6310
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
6261
6311
|
`
|
|
6262
6312
|
);
|
|
6263
|
-
|
|
6313
|
+
candidate = fromSessionName;
|
|
6314
|
+
} else {
|
|
6315
|
+
candidate = fromCache;
|
|
6264
6316
|
}
|
|
6265
|
-
return fromCache;
|
|
6266
6317
|
}
|
|
6267
6318
|
} catch {
|
|
6268
6319
|
}
|
|
6269
|
-
|
|
6320
|
+
if (!candidate) {
|
|
6321
|
+
candidate = fromSessionName ?? mySession;
|
|
6322
|
+
}
|
|
6323
|
+
if (candidate && isRootSession(candidate)) {
|
|
6324
|
+
try {
|
|
6325
|
+
const transport = getTransport();
|
|
6326
|
+
const liveSessions = transport.listSessions();
|
|
6327
|
+
if (!liveSessions.includes(candidate)) {
|
|
6328
|
+
const liveRoots = liveSessions.filter((s) => isRootSession(s));
|
|
6329
|
+
if (liveRoots.length === 1) {
|
|
6330
|
+
process.stderr.write(
|
|
6331
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. Using live coordinator "${liveRoots[0]}".
|
|
6332
|
+
`
|
|
6333
|
+
);
|
|
6334
|
+
return liveRoots[0];
|
|
6335
|
+
} else if (liveRoots.length > 1) {
|
|
6336
|
+
const base = candidate.replace(/\d+$/, "");
|
|
6337
|
+
const match = liveRoots.find((s) => s.startsWith(base));
|
|
6338
|
+
const chosen = match ?? liveRoots[0];
|
|
6339
|
+
process.stderr.write(
|
|
6340
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. ${liveRoots.length} live roots found, using "${chosen}".
|
|
6341
|
+
`
|
|
6342
|
+
);
|
|
6343
|
+
return chosen;
|
|
6344
|
+
}
|
|
6345
|
+
process.stderr.write(
|
|
6346
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead and no live coordinator found.
|
|
6347
|
+
`
|
|
6348
|
+
);
|
|
6349
|
+
}
|
|
6350
|
+
} catch {
|
|
6351
|
+
}
|
|
6352
|
+
}
|
|
6353
|
+
return candidate;
|
|
6270
6354
|
}
|
|
6271
6355
|
function isEmployeeAlive(sessionName) {
|
|
6272
6356
|
return getTransport().isAlive(sessionName);
|
|
@@ -6668,7 +6752,12 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
6668
6752
|
}
|
|
6669
6753
|
const spawnCwd = opts?.cwd ?? projectDir;
|
|
6670
6754
|
const useExeAgent = !!(opts?.model && opts?.provider);
|
|
6671
|
-
const
|
|
6755
|
+
const baseRtConfig = getAgentRuntime(employeeName);
|
|
6756
|
+
const agentRtConfig = {
|
|
6757
|
+
...baseRtConfig,
|
|
6758
|
+
...opts?.runtimeOverride ? { runtime: opts.runtimeOverride } : {},
|
|
6759
|
+
...opts?.modelOverride ? { model: opts.modelOverride } : {}
|
|
6760
|
+
};
|
|
6672
6761
|
const useCodex = !useExeAgent && agentRtConfig.runtime === "codex";
|
|
6673
6762
|
const useOpencode = !useExeAgent && !useCodex && agentRtConfig.runtime === "opencode";
|
|
6674
6763
|
const ccProvider = useExeAgent || useCodex || useOpencode ? DEFAULT_PROVIDER : detectActiveProvider();
|
|
@@ -7961,6 +8050,20 @@ var init_platform_procedures = __esm({
|
|
|
7961
8050
|
priority: "p1",
|
|
7962
8051
|
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."
|
|
7963
8052
|
},
|
|
8053
|
+
// --- Tool guidance ---
|
|
8054
|
+
{
|
|
8055
|
+
title: "How to use company_actions \u2014 execute business actions through gateway connectors",
|
|
8056
|
+
domain: "tools",
|
|
8057
|
+
priority: "p2",
|
|
8058
|
+
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."
|
|
8059
|
+
},
|
|
8060
|
+
// --- Release awareness ---
|
|
8061
|
+
{
|
|
8062
|
+
title: "What's New check \u2014 surface new features after update",
|
|
8063
|
+
domain: "support",
|
|
8064
|
+
priority: "p1",
|
|
8065
|
+
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."
|
|
8066
|
+
},
|
|
7964
8067
|
// --- Platform vs Customer ownership ---
|
|
7965
8068
|
{
|
|
7966
8069
|
title: "What the platform provides vs what you customize",
|
|
@@ -8049,13 +8152,13 @@ var init_platform_procedures = __esm({
|
|
|
8049
8152
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
8050
8153
|
domain: "tool-use",
|
|
8051
8154
|
priority: "p1",
|
|
8052
|
-
content: `memory(action="recall") / recall_my_memory: search
|
|
8155
|
+
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.`
|
|
8053
8156
|
},
|
|
8054
8157
|
{
|
|
8055
8158
|
title: "MCP tools \u2014 task orchestration",
|
|
8056
8159
|
domain: "tool-use",
|
|
8057
8160
|
priority: "p1",
|
|
8058
|
-
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.'
|
|
8161
|
+
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.'
|
|
8059
8162
|
},
|
|
8060
8163
|
{
|
|
8061
8164
|
title: "MCP tools \u2014 knowledge graph (GraphRAG)",
|
|
@@ -8085,7 +8188,7 @@ var init_platform_procedures = __esm({
|
|
|
8085
8188
|
title: "MCP tools \u2014 admin, config, and operations",
|
|
8086
8189
|
domain: "tool-use",
|
|
8087
8190
|
priority: "p1",
|
|
8088
|
-
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.'
|
|
8191
|
+
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.'
|
|
8089
8192
|
}
|
|
8090
8193
|
];
|
|
8091
8194
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -8769,6 +8872,8 @@ async function writeMemory(record) {
|
|
|
8769
8872
|
source_type: record.source_type ?? null,
|
|
8770
8873
|
tier: record.tier ?? classifyTier(record),
|
|
8771
8874
|
supersedes_id: record.supersedes_id ?? null,
|
|
8875
|
+
valid_from: record.valid_from ?? record.timestamp,
|
|
8876
|
+
invalid_at: record.invalid_at ?? null,
|
|
8772
8877
|
draft: record.draft ? 1 : 0,
|
|
8773
8878
|
memory_type: memoryType,
|
|
8774
8879
|
trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
|
|
@@ -8787,7 +8892,8 @@ async function writeMemory(record) {
|
|
|
8787
8892
|
token_cost: record.token_cost ?? null,
|
|
8788
8893
|
audience: record.audience ?? null,
|
|
8789
8894
|
language_type: record.language_type ?? inferLanguageType(record),
|
|
8790
|
-
parent_memory_id: record.parent_memory_id ?? null
|
|
8895
|
+
parent_memory_id: record.parent_memory_id ?? null,
|
|
8896
|
+
procedure_for: record.procedure_for ?? null
|
|
8791
8897
|
};
|
|
8792
8898
|
_pendingRecords.push(dbRow);
|
|
8793
8899
|
orgBus.emit({
|
|
@@ -8842,6 +8948,8 @@ async function flushBatch() {
|
|
|
8842
8948
|
const sourceType = row.source_type ?? null;
|
|
8843
8949
|
const tier = row.tier ?? 3;
|
|
8844
8950
|
const supersedesId = row.supersedes_id ?? null;
|
|
8951
|
+
const validFrom = row.valid_from ?? row.timestamp;
|
|
8952
|
+
const invalidAt = row.invalid_at ?? null;
|
|
8845
8953
|
const draft = row.draft ? 1 : 0;
|
|
8846
8954
|
const memoryType = row.memory_type ?? "raw";
|
|
8847
8955
|
const trajectory = row.trajectory ?? null;
|
|
@@ -8861,15 +8969,16 @@ async function flushBatch() {
|
|
|
8861
8969
|
const audience = row.audience ?? null;
|
|
8862
8970
|
const languageType = row.language_type ?? null;
|
|
8863
8971
|
const parentMemoryId = row.parent_memory_id ?? null;
|
|
8972
|
+
const procedureFor = row.procedure_for ?? null;
|
|
8864
8973
|
const cols = `id, agent_id, agent_role, session_id, timestamp,
|
|
8865
8974
|
tool_name, project_name,
|
|
8866
8975
|
has_error, raw_text, vector, version, task_id, importance, status,
|
|
8867
8976
|
confidence, last_accessed,
|
|
8868
8977
|
workspace_id, document_id, user_id, char_offset, page_number,
|
|
8869
|
-
source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
|
|
8978
|
+
source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
|
|
8870
8979
|
intent, outcome, domain, referenced_entities, retrieval_count,
|
|
8871
8980
|
chain_position, review_status, context_window_pct, file_paths, commit_hash,
|
|
8872
|
-
duration_ms, token_cost, audience, language_type, parent_memory_id`;
|
|
8981
|
+
duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for`;
|
|
8873
8982
|
const metaArgs = [
|
|
8874
8983
|
intent,
|
|
8875
8984
|
outcome,
|
|
@@ -8885,7 +8994,8 @@ async function flushBatch() {
|
|
|
8885
8994
|
tokenCost,
|
|
8886
8995
|
audience,
|
|
8887
8996
|
languageType,
|
|
8888
|
-
parentMemoryId
|
|
8997
|
+
parentMemoryId,
|
|
8998
|
+
procedureFor
|
|
8889
8999
|
];
|
|
8890
9000
|
const baseArgs = [
|
|
8891
9001
|
row.id,
|
|
@@ -8914,6 +9024,8 @@ async function flushBatch() {
|
|
|
8914
9024
|
sourceType,
|
|
8915
9025
|
tier,
|
|
8916
9026
|
supersedesId,
|
|
9027
|
+
validFrom,
|
|
9028
|
+
invalidAt,
|
|
8917
9029
|
draft,
|
|
8918
9030
|
memoryType,
|
|
8919
9031
|
trajectory,
|
|
@@ -8921,8 +9033,8 @@ async function flushBatch() {
|
|
|
8921
9033
|
];
|
|
8922
9034
|
return {
|
|
8923
9035
|
sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
|
|
8924
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
8925
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
9036
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
9037
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
8926
9038
|
args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
|
|
8927
9039
|
};
|
|
8928
9040
|
};
|
|
@@ -9038,6 +9150,12 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
9038
9150
|
AND vector IS NOT NULL${statusFilter}${draftFilter}
|
|
9039
9151
|
AND COALESCE(confidence, 0.7) >= 0.3`;
|
|
9040
9152
|
const args = [agentId];
|
|
9153
|
+
if (options?.asOf) {
|
|
9154
|
+
sql += ` AND (valid_from IS NULL OR valid_from <= ?) AND (invalid_at IS NULL OR invalid_at > ?)`;
|
|
9155
|
+
args.push(options.asOf, options.asOf);
|
|
9156
|
+
} else {
|
|
9157
|
+
sql += ` AND invalid_at IS NULL`;
|
|
9158
|
+
}
|
|
9041
9159
|
const scope = buildWikiScopeFilter(options, "");
|
|
9042
9160
|
sql += scope.clause;
|
|
9043
9161
|
args.push(...scope.args);
|
|
@@ -3349,6 +3349,20 @@ async function ensureSchema() {
|
|
|
3349
3349
|
});
|
|
3350
3350
|
} catch {
|
|
3351
3351
|
}
|
|
3352
|
+
try {
|
|
3353
|
+
await client.execute({
|
|
3354
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
3355
|
+
args: []
|
|
3356
|
+
});
|
|
3357
|
+
} catch {
|
|
3358
|
+
}
|
|
3359
|
+
try {
|
|
3360
|
+
await client.execute({
|
|
3361
|
+
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
3362
|
+
args: []
|
|
3363
|
+
});
|
|
3364
|
+
} catch {
|
|
3365
|
+
}
|
|
3352
3366
|
await client.executeMultiple(`
|
|
3353
3367
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
3354
3368
|
content_text,
|
|
@@ -3600,6 +3614,22 @@ async function ensureSchema() {
|
|
|
3600
3614
|
);
|
|
3601
3615
|
} catch {
|
|
3602
3616
|
}
|
|
3617
|
+
for (const col of [
|
|
3618
|
+
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
3619
|
+
"ALTER TABLE memories ADD COLUMN invalid_at TEXT"
|
|
3620
|
+
]) {
|
|
3621
|
+
try {
|
|
3622
|
+
await client.execute(col);
|
|
3623
|
+
} catch {
|
|
3624
|
+
}
|
|
3625
|
+
}
|
|
3626
|
+
try {
|
|
3627
|
+
await client.execute({
|
|
3628
|
+
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
3629
|
+
args: []
|
|
3630
|
+
});
|
|
3631
|
+
} catch {
|
|
3632
|
+
}
|
|
3603
3633
|
try {
|
|
3604
3634
|
await client.execute({
|
|
3605
3635
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
@@ -3642,6 +3672,13 @@ async function ensureSchema() {
|
|
|
3642
3672
|
} catch {
|
|
3643
3673
|
}
|
|
3644
3674
|
}
|
|
3675
|
+
try {
|
|
3676
|
+
await client.execute({
|
|
3677
|
+
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
3678
|
+
args: []
|
|
3679
|
+
});
|
|
3680
|
+
} catch {
|
|
3681
|
+
}
|
|
3645
3682
|
try {
|
|
3646
3683
|
await client.execute({
|
|
3647
3684
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
@@ -3702,7 +3739,7 @@ import { pathToFileURL as pathToFileURL2 } from "url";
|
|
|
3702
3739
|
import os7 from "os";
|
|
3703
3740
|
import path10 from "path";
|
|
3704
3741
|
import { jwtVerify, importSPKI } from "jose";
|
|
3705
|
-
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH;
|
|
3742
|
+
var LICENSE_PATH, CACHE_PATH, DEVICE_ID_PATH, API_BASE;
|
|
3706
3743
|
var init_license = __esm({
|
|
3707
3744
|
"src/lib/license.ts"() {
|
|
3708
3745
|
"use strict";
|
|
@@ -3710,6 +3747,7 @@ var init_license = __esm({
|
|
|
3710
3747
|
LICENSE_PATH = path10.join(EXE_AI_DIR, "license.key");
|
|
3711
3748
|
CACHE_PATH = path10.join(EXE_AI_DIR, "license-cache.json");
|
|
3712
3749
|
DEVICE_ID_PATH = path10.join(EXE_AI_DIR, "device-id");
|
|
3750
|
+
API_BASE = process.env.EXE_CLOUD_ENDPOINT ?? "https://askexe.com/cloud";
|
|
3713
3751
|
}
|
|
3714
3752
|
});
|
|
3715
3753
|
|
|
@@ -3753,6 +3791,9 @@ import { fileURLToPath as fileURLToPath2 } from "url";
|
|
|
3753
3791
|
function getMySession() {
|
|
3754
3792
|
return getTransport().getMySession();
|
|
3755
3793
|
}
|
|
3794
|
+
function isRootSession(name) {
|
|
3795
|
+
return name.length > 0 && !name.includes("-");
|
|
3796
|
+
}
|
|
3756
3797
|
function extractRootExe(name) {
|
|
3757
3798
|
if (!name) return null;
|
|
3758
3799
|
if (!name.includes("-")) return name;
|
|
@@ -3768,9 +3809,13 @@ function getParentExe(sessionKey) {
|
|
|
3768
3809
|
}
|
|
3769
3810
|
}
|
|
3770
3811
|
function resolveExeSession() {
|
|
3812
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
3813
|
+
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
3814
|
+
}
|
|
3771
3815
|
const mySession = getMySession();
|
|
3772
3816
|
if (!mySession) return null;
|
|
3773
3817
|
const fromSessionName = extractRootExe(mySession);
|
|
3818
|
+
let candidate = null;
|
|
3774
3819
|
try {
|
|
3775
3820
|
const key = getSessionKey();
|
|
3776
3821
|
const parentExe = getParentExe(key);
|
|
@@ -3781,13 +3826,47 @@ function resolveExeSession() {
|
|
|
3781
3826
|
`[tmux-routing] WARN: cache says "${fromCache}" but session name says "${fromSessionName}". Trusting session name.
|
|
3782
3827
|
`
|
|
3783
3828
|
);
|
|
3784
|
-
|
|
3829
|
+
candidate = fromSessionName;
|
|
3830
|
+
} else {
|
|
3831
|
+
candidate = fromCache;
|
|
3785
3832
|
}
|
|
3786
|
-
return fromCache;
|
|
3787
3833
|
}
|
|
3788
3834
|
} catch {
|
|
3789
3835
|
}
|
|
3790
|
-
|
|
3836
|
+
if (!candidate) {
|
|
3837
|
+
candidate = fromSessionName ?? mySession;
|
|
3838
|
+
}
|
|
3839
|
+
if (candidate && isRootSession(candidate)) {
|
|
3840
|
+
try {
|
|
3841
|
+
const transport = getTransport();
|
|
3842
|
+
const liveSessions = transport.listSessions();
|
|
3843
|
+
if (!liveSessions.includes(candidate)) {
|
|
3844
|
+
const liveRoots = liveSessions.filter((s) => isRootSession(s));
|
|
3845
|
+
if (liveRoots.length === 1) {
|
|
3846
|
+
process.stderr.write(
|
|
3847
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. Using live coordinator "${liveRoots[0]}".
|
|
3848
|
+
`
|
|
3849
|
+
);
|
|
3850
|
+
return liveRoots[0];
|
|
3851
|
+
} else if (liveRoots.length > 1) {
|
|
3852
|
+
const base = candidate.replace(/\d+$/, "");
|
|
3853
|
+
const match = liveRoots.find((s) => s.startsWith(base));
|
|
3854
|
+
const chosen = match ?? liveRoots[0];
|
|
3855
|
+
process.stderr.write(
|
|
3856
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead. ${liveRoots.length} live roots found, using "${chosen}".
|
|
3857
|
+
`
|
|
3858
|
+
);
|
|
3859
|
+
return chosen;
|
|
3860
|
+
}
|
|
3861
|
+
process.stderr.write(
|
|
3862
|
+
`[tmux-routing] WARN: resolved session "${candidate}" is dead and no live coordinator found.
|
|
3863
|
+
`
|
|
3864
|
+
);
|
|
3865
|
+
}
|
|
3866
|
+
} catch {
|
|
3867
|
+
}
|
|
3868
|
+
}
|
|
3869
|
+
return candidate;
|
|
3791
3870
|
}
|
|
3792
3871
|
var SPAWN_LOCK_DIR, SESSION_CACHE, INTERCOM_LOG2, DEBOUNCE_FILE, DEBOUNCE_CLEANUP_AGE_MS;
|
|
3793
3872
|
var init_tmux_routing = __esm({
|
|
@@ -5107,6 +5186,20 @@ var init_platform_procedures = __esm({
|
|
|
5107
5186
|
priority: "p1",
|
|
5108
5187
|
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."
|
|
5109
5188
|
},
|
|
5189
|
+
// --- Tool guidance ---
|
|
5190
|
+
{
|
|
5191
|
+
title: "How to use company_actions \u2014 execute business actions through gateway connectors",
|
|
5192
|
+
domain: "tools",
|
|
5193
|
+
priority: "p2",
|
|
5194
|
+
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."
|
|
5195
|
+
},
|
|
5196
|
+
// --- Release awareness ---
|
|
5197
|
+
{
|
|
5198
|
+
title: "What's New check \u2014 surface new features after update",
|
|
5199
|
+
domain: "support",
|
|
5200
|
+
priority: "p1",
|
|
5201
|
+
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."
|
|
5202
|
+
},
|
|
5110
5203
|
// --- Platform vs Customer ownership ---
|
|
5111
5204
|
{
|
|
5112
5205
|
title: "What the platform provides vs what you customize",
|
|
@@ -5195,13 +5288,13 @@ var init_platform_procedures = __esm({
|
|
|
5195
5288
|
title: "MCP tools \u2014 memory, decision, and search",
|
|
5196
5289
|
domain: "tool-use",
|
|
5197
5290
|
priority: "p1",
|
|
5198
|
-
content: `memory(action="recall") / recall_my_memory: search
|
|
5291
|
+
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.`
|
|
5199
5292
|
},
|
|
5200
5293
|
{
|
|
5201
5294
|
title: "MCP tools \u2014 task orchestration",
|
|
5202
5295
|
domain: "tool-use",
|
|
5203
5296
|
priority: "p1",
|
|
5204
|
-
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.'
|
|
5297
|
+
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.'
|
|
5205
5298
|
},
|
|
5206
5299
|
{
|
|
5207
5300
|
title: "MCP tools \u2014 knowledge graph (GraphRAG)",
|
|
@@ -5231,7 +5324,7 @@ var init_platform_procedures = __esm({
|
|
|
5231
5324
|
title: "MCP tools \u2014 admin, config, and operations",
|
|
5232
5325
|
domain: "tool-use",
|
|
5233
5326
|
priority: "p1",
|
|
5234
|
-
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.'
|
|
5327
|
+
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.'
|
|
5235
5328
|
}
|
|
5236
5329
|
];
|
|
5237
5330
|
PLATFORM_PROCEDURE_TITLES = new Set(
|
|
@@ -5915,6 +6008,8 @@ async function writeMemory(record) {
|
|
|
5915
6008
|
source_type: record.source_type ?? null,
|
|
5916
6009
|
tier: record.tier ?? classifyTier(record),
|
|
5917
6010
|
supersedes_id: record.supersedes_id ?? null,
|
|
6011
|
+
valid_from: record.valid_from ?? record.timestamp,
|
|
6012
|
+
invalid_at: record.invalid_at ?? null,
|
|
5918
6013
|
draft: record.draft ? 1 : 0,
|
|
5919
6014
|
memory_type: memoryType,
|
|
5920
6015
|
trajectory: record.trajectory ? JSON.stringify(record.trajectory) : null,
|
|
@@ -5933,7 +6028,8 @@ async function writeMemory(record) {
|
|
|
5933
6028
|
token_cost: record.token_cost ?? null,
|
|
5934
6029
|
audience: record.audience ?? null,
|
|
5935
6030
|
language_type: record.language_type ?? inferLanguageType(record),
|
|
5936
|
-
parent_memory_id: record.parent_memory_id ?? null
|
|
6031
|
+
parent_memory_id: record.parent_memory_id ?? null,
|
|
6032
|
+
procedure_for: record.procedure_for ?? null
|
|
5937
6033
|
};
|
|
5938
6034
|
_pendingRecords.push(dbRow);
|
|
5939
6035
|
orgBus.emit({
|
|
@@ -5988,6 +6084,8 @@ async function flushBatch() {
|
|
|
5988
6084
|
const sourceType = row.source_type ?? null;
|
|
5989
6085
|
const tier = row.tier ?? 3;
|
|
5990
6086
|
const supersedesId = row.supersedes_id ?? null;
|
|
6087
|
+
const validFrom = row.valid_from ?? row.timestamp;
|
|
6088
|
+
const invalidAt = row.invalid_at ?? null;
|
|
5991
6089
|
const draft = row.draft ? 1 : 0;
|
|
5992
6090
|
const memoryType = row.memory_type ?? "raw";
|
|
5993
6091
|
const trajectory = row.trajectory ?? null;
|
|
@@ -6007,15 +6105,16 @@ async function flushBatch() {
|
|
|
6007
6105
|
const audience = row.audience ?? null;
|
|
6008
6106
|
const languageType = row.language_type ?? null;
|
|
6009
6107
|
const parentMemoryId = row.parent_memory_id ?? null;
|
|
6108
|
+
const procedureFor = row.procedure_for ?? null;
|
|
6010
6109
|
const cols = `id, agent_id, agent_role, session_id, timestamp,
|
|
6011
6110
|
tool_name, project_name,
|
|
6012
6111
|
has_error, raw_text, vector, version, task_id, importance, status,
|
|
6013
6112
|
confidence, last_accessed,
|
|
6014
6113
|
workspace_id, document_id, user_id, char_offset, page_number,
|
|
6015
|
-
source_path, source_type, tier, supersedes_id, draft, memory_type, trajectory, content_hash,
|
|
6114
|
+
source_path, source_type, tier, supersedes_id, valid_from, invalid_at, draft, memory_type, trajectory, content_hash,
|
|
6016
6115
|
intent, outcome, domain, referenced_entities, retrieval_count,
|
|
6017
6116
|
chain_position, review_status, context_window_pct, file_paths, commit_hash,
|
|
6018
|
-
duration_ms, token_cost, audience, language_type, parent_memory_id`;
|
|
6117
|
+
duration_ms, token_cost, audience, language_type, parent_memory_id, procedure_for`;
|
|
6019
6118
|
const metaArgs = [
|
|
6020
6119
|
intent,
|
|
6021
6120
|
outcome,
|
|
@@ -6031,7 +6130,8 @@ async function flushBatch() {
|
|
|
6031
6130
|
tokenCost,
|
|
6032
6131
|
audience,
|
|
6033
6132
|
languageType,
|
|
6034
|
-
parentMemoryId
|
|
6133
|
+
parentMemoryId,
|
|
6134
|
+
procedureFor
|
|
6035
6135
|
];
|
|
6036
6136
|
const baseArgs = [
|
|
6037
6137
|
row.id,
|
|
@@ -6060,6 +6160,8 @@ async function flushBatch() {
|
|
|
6060
6160
|
sourceType,
|
|
6061
6161
|
tier,
|
|
6062
6162
|
supersedesId,
|
|
6163
|
+
validFrom,
|
|
6164
|
+
invalidAt,
|
|
6063
6165
|
draft,
|
|
6064
6166
|
memoryType,
|
|
6065
6167
|
trajectory,
|
|
@@ -6067,8 +6169,8 @@ async function flushBatch() {
|
|
|
6067
6169
|
];
|
|
6068
6170
|
return {
|
|
6069
6171
|
sql: hasVector ? `INSERT OR IGNORE INTO memories (${cols})
|
|
6070
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
6071
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
6172
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, vector32(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)` : `INSERT OR IGNORE INTO memories (${cols})
|
|
6173
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
6072
6174
|
args: hasVector ? [...baseArgs, vectorToBlob(row.vector), ...sharedArgs, ...metaArgs] : [...baseArgs, ...sharedArgs, ...metaArgs]
|
|
6073
6175
|
};
|
|
6074
6176
|
};
|
|
@@ -6184,6 +6286,12 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
6184
6286
|
AND vector IS NOT NULL${statusFilter}${draftFilter}
|
|
6185
6287
|
AND COALESCE(confidence, 0.7) >= 0.3`;
|
|
6186
6288
|
const args = [agentId];
|
|
6289
|
+
if (options?.asOf) {
|
|
6290
|
+
sql += ` AND (valid_from IS NULL OR valid_from <= ?) AND (invalid_at IS NULL OR invalid_at > ?)`;
|
|
6291
|
+
args.push(options.asOf, options.asOf);
|
|
6292
|
+
} else {
|
|
6293
|
+
sql += ` AND invalid_at IS NULL`;
|
|
6294
|
+
}
|
|
6187
6295
|
const scope = buildWikiScopeFilter(options, "");
|
|
6188
6296
|
sql += scope.clause;
|
|
6189
6297
|
args.push(...scope.args);
|