@runcore-sh/runcore 0.4.0 → 0.5.1
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/dictionary.json +2 -2
- package/dist/activity/log.js +2 -2
- package/dist/activity/log.js.map +1 -1
- package/dist/agents/governed-spawn.d.ts.map +1 -1
- package/dist/cli.js +101 -11
- package/dist/cli.js.map +1 -1
- package/dist/extensions/cache.d.ts +57 -0
- package/dist/extensions/cache.d.ts.map +1 -0
- package/dist/extensions/cache.js +173 -0
- package/dist/extensions/cache.js.map +1 -0
- package/dist/extensions/client.d.ts +55 -0
- package/dist/extensions/client.d.ts.map +1 -0
- package/dist/extensions/client.js +120 -0
- package/dist/extensions/client.js.map +1 -0
- package/dist/extensions/index.d.ts +13 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +12 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/loader.d.ts +50 -0
- package/dist/extensions/loader.d.ts.map +1 -0
- package/dist/extensions/loader.js +166 -0
- package/dist/extensions/loader.js.map +1 -0
- package/dist/extensions/manifest.d.ts +38 -0
- package/dist/extensions/manifest.d.ts.map +1 -0
- package/dist/extensions/manifest.js +17 -0
- package/dist/extensions/manifest.js.map +1 -0
- package/dist/extensions/stubs.d.ts +27 -0
- package/dist/extensions/stubs.d.ts.map +1 -0
- package/dist/extensions/stubs.js +45 -0
- package/dist/extensions/stubs.js.map +1 -0
- package/dist/lib/audit.js +2 -2
- package/dist/lib/audit.js.map +1 -1
- package/dist/lib/brain-migrate.d.ts +21 -0
- package/dist/lib/brain-migrate.d.ts.map +1 -0
- package/dist/lib/brain-migrate.js +137 -0
- package/dist/lib/brain-migrate.js.map +1 -0
- package/dist/lib/paths.d.ts +27 -0
- package/dist/lib/paths.d.ts.map +1 -1
- package/dist/lib/paths.js +65 -0
- package/dist/lib/paths.js.map +1 -1
- package/dist/llm/call-log.d.ts +40 -0
- package/dist/llm/call-log.d.ts.map +1 -0
- package/dist/llm/call-log.js +35 -0
- package/dist/llm/call-log.js.map +1 -0
- package/dist/llm/complete.d.ts +6 -0
- package/dist/llm/complete.d.ts.map +1 -1
- package/dist/llm/complete.js +27 -0
- package/dist/llm/complete.js.map +1 -1
- package/dist/mcp-server.js +118 -2
- package/dist/mcp-server.js.map +1 -1
- package/dist/memory/file-backed.d.ts +4 -0
- package/dist/memory/file-backed.d.ts.map +1 -1
- package/dist/memory/file-backed.js +4 -0
- package/dist/memory/file-backed.js.map +1 -1
- package/dist/memory/vector-index.d.ts +4 -12
- package/dist/memory/vector-index.d.ts.map +1 -1
- package/dist/memory/vector-index.js +11 -93
- package/dist/memory/vector-index.js.map +1 -1
- package/dist/search/brain-docs.d.ts +17 -7
- package/dist/search/brain-docs.d.ts.map +1 -1
- package/dist/search/brain-docs.js +170 -52
- package/dist/search/brain-docs.js.map +1 -1
- package/dist/search/brain-rag.d.ts +45 -0
- package/dist/search/brain-rag.d.ts.map +1 -0
- package/dist/search/brain-rag.js +275 -0
- package/dist/search/brain-rag.js.map +1 -0
- package/dist/search/chunker.d.ts +24 -0
- package/dist/search/chunker.d.ts.map +1 -0
- package/dist/search/chunker.js +95 -0
- package/dist/search/chunker.js.map +1 -0
- package/dist/search/embedder.d.ts +16 -0
- package/dist/search/embedder.d.ts.map +1 -0
- package/dist/search/embedder.js +108 -0
- package/dist/search/embedder.js.map +1 -0
- package/dist/search/file-watcher.d.ts +11 -0
- package/dist/search/file-watcher.d.ts.map +1 -0
- package/dist/search/file-watcher.js +86 -0
- package/dist/search/file-watcher.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +814 -472
- package/dist/server.js.map +1 -1
- package/dist/sessions/store.d.ts +9 -0
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js.map +1 -1
- package/dist/settings.d.ts +26 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +78 -2
- package/dist/settings.js.map +1 -1
- package/dist/tracing/init.d.ts +1 -1
- package/dist/tracing/init.d.ts.map +1 -1
- package/dist/utils/logger.js +2 -2
- package/dist/utils/logger.js.map +1 -1
- package/module-tiers.json +164 -0
- package/package.json +9 -13
- package/public/avatar/cache/1184385ec5522b57.mp4 +0 -0
- package/public/avatar/cache/1f15f6a1ebd7e439.mp4 +0 -0
- package/public/avatar/cache/2c7e47ff0bdeb8d1.mp4 +0 -0
- package/public/avatar/cache/5f308566f7abb8f2.mp4 +0 -0
- package/public/avatar/cache/62f9cfba848d724e.mp4 +0 -0
- package/public/avatar/cache/6d64e657e6bf2aab.mp4 +0 -0
- package/public/avatar/cache/763ad0349e0b6f26.mp4 +0 -0
- package/public/avatar/cache/81a516cfd461b2b9.mp4 +0 -0
- package/public/avatar/cache/9366de15fd6910ca.mp4 +0 -0
- package/public/avatar/cache/ade41a846b283895.mp4 +0 -0
- package/public/avatar/cache/b6066e5c65383eec.mp4 +0 -0
- package/public/avatar/cache/edadb75d37891fc7.mp4 +0 -0
- package/public/avatar/cache/f0ae159640621dd9.mp4 +0 -0
- package/public/avatar/cache/fc2e5419adf29d96.mp4 +0 -0
- package/public/index.html +379 -59
- package/dist/agents/autonomous.js +0 -749
- package/dist/agents/autonomous.js.map +0 -1
- package/dist/agents/commit.js +0 -113
- package/dist/agents/commit.js.map +0 -1
- package/dist/agents/continue.js +0 -158
- package/dist/agents/continue.js.map +0 -1
- package/dist/agents/cooldown.js +0 -397
- package/dist/agents/cooldown.js.map +0 -1
- package/dist/agents/dedup-guard.js +0 -131
- package/dist/agents/dedup-guard.js.map +0 -1
- package/dist/agents/feed.js +0 -176
- package/dist/agents/feed.js.map +0 -1
- package/dist/agents/governance.js +0 -292
- package/dist/agents/governance.js.map +0 -1
- package/dist/agents/governed-spawn.js +0 -192
- package/dist/agents/governed-spawn.js.map +0 -1
- package/dist/agents/heartbeat.js +0 -324
- package/dist/agents/heartbeat.js.map +0 -1
- package/dist/agents/instance-manager.js +0 -850
- package/dist/agents/instance-manager.js.map +0 -1
- package/dist/agents/issue-reporter.js +0 -123
- package/dist/agents/issue-reporter.js.map +0 -1
- package/dist/agents/issues.js +0 -141
- package/dist/agents/issues.js.map +0 -1
- package/dist/agents/locks.js +0 -234
- package/dist/agents/locks.js.map +0 -1
- package/dist/agents/memory.js +0 -93
- package/dist/agents/memory.js.map +0 -1
- package/dist/agents/monitor.js +0 -235
- package/dist/agents/monitor.js.map +0 -1
- package/dist/agents/orchestration.js +0 -715
- package/dist/agents/orchestration.js.map +0 -1
- package/dist/agents/recover.js +0 -166
- package/dist/agents/recover.js.map +0 -1
- package/dist/agents/reflection.js +0 -199
- package/dist/agents/reflection.js.map +0 -1
- package/dist/agents/runtime/bus.js +0 -174
- package/dist/agents/runtime/bus.js.map +0 -1
- package/dist/agents/runtime/config.js +0 -101
- package/dist/agents/runtime/config.js.map +0 -1
- package/dist/agents/runtime/driver.js +0 -214
- package/dist/agents/runtime/driver.js.map +0 -1
- package/dist/agents/runtime/errors.js +0 -40
- package/dist/agents/runtime/errors.js.map +0 -1
- package/dist/agents/runtime/index.js +0 -54
- package/dist/agents/runtime/index.js.map +0 -1
- package/dist/agents/runtime/lifecycle.js +0 -116
- package/dist/agents/runtime/lifecycle.js.map +0 -1
- package/dist/agents/runtime/manager.js +0 -948
- package/dist/agents/runtime/manager.js.map +0 -1
- package/dist/agents/runtime/registry.js +0 -195
- package/dist/agents/runtime/registry.js.map +0 -1
- package/dist/agents/runtime/resources.js +0 -146
- package/dist/agents/runtime/resources.js.map +0 -1
- package/dist/agents/runtime/types.js +0 -24
- package/dist/agents/runtime/types.js.map +0 -1
- package/dist/agents/spawn-policy.js +0 -202
- package/dist/agents/spawn-policy.js.map +0 -1
- package/dist/agents/spawn.js +0 -970
- package/dist/agents/spawn.js.map +0 -1
- package/dist/agents/triage.js +0 -81
- package/dist/agents/triage.js.map +0 -1
- package/dist/agents/workflow.js +0 -543
- package/dist/agents/workflow.js.map +0 -1
- package/dist/avatar/client.js +0 -172
- package/dist/avatar/client.js.map +0 -1
- package/dist/avatar/sidecar.js +0 -125
- package/dist/avatar/sidecar.js.map +0 -1
- package/dist/browser/sessions.js +0 -122
- package/dist/browser/sessions.js.map +0 -1
- package/dist/capabilities/definitions/browser.js +0 -242
- package/dist/capabilities/definitions/browser.js.map +0 -1
- package/dist/channels/whatsapp.js +0 -200
- package/dist/channels/whatsapp.js.map +0 -1
- package/dist/credentials/store.js +0 -189
- package/dist/credentials/store.js.map +0 -1
- package/dist/files/deep-index.js +0 -337
- package/dist/files/deep-index.js.map +0 -1
- package/dist/files/extract.js +0 -33
- package/dist/files/extract.js.map +0 -1
- package/dist/files/gdrive.js +0 -246
- package/dist/files/gdrive.js.map +0 -1
- package/dist/github/client.js +0 -408
- package/dist/github/client.js.map +0 -1
- package/dist/github/commit-analysis.js +0 -276
- package/dist/github/commit-analysis.js.map +0 -1
- package/dist/github/contributor-stats.js +0 -119
- package/dist/github/contributor-stats.js.map +0 -1
- package/dist/github/issue-sla.js +0 -220
- package/dist/github/issue-sla.js.map +0 -1
- package/dist/github/issue-triage.js +0 -286
- package/dist/github/issue-triage.js.map +0 -1
- package/dist/github/pr-readiness.js +0 -197
- package/dist/github/pr-readiness.js.map +0 -1
- package/dist/github/pr-review.js +0 -410
- package/dist/github/pr-review.js.map +0 -1
- package/dist/github/release-notes.js +0 -227
- package/dist/github/release-notes.js.map +0 -1
- package/dist/github/repo-health.js +0 -303
- package/dist/github/repo-health.js.map +0 -1
- package/dist/github/retry.js +0 -117
- package/dist/github/retry.js.map +0 -1
- package/dist/github/types.js +0 -8
- package/dist/github/types.js.map +0 -1
- package/dist/github/webhooks.js +0 -153
- package/dist/github/webhooks.js.map +0 -1
- package/dist/google/auth.js +0 -325
- package/dist/google/auth.js.map +0 -1
- package/dist/google/calendar-timer.js +0 -91
- package/dist/google/calendar-timer.js.map +0 -1
- package/dist/google/calendar.js +0 -270
- package/dist/google/calendar.js.map +0 -1
- package/dist/google/docs.js +0 -309
- package/dist/google/docs.js.map +0 -1
- package/dist/google/gmail-send.js +0 -219
- package/dist/google/gmail-send.js.map +0 -1
- package/dist/google/gmail-timer.js +0 -223
- package/dist/google/gmail-timer.js.map +0 -1
- package/dist/google/gmail.js +0 -470
- package/dist/google/gmail.js.map +0 -1
- package/dist/google/plugin.js +0 -169
- package/dist/google/plugin.js.map +0 -1
- package/dist/google/tasks-timer.js +0 -107
- package/dist/google/tasks-timer.js.map +0 -1
- package/dist/google/tasks.js +0 -331
- package/dist/google/tasks.js.map +0 -1
- package/dist/google/temporal.js +0 -176
- package/dist/google/temporal.js.map +0 -1
- package/dist/integrations/gate.js +0 -100
- package/dist/integrations/gate.js.map +0 -1
- package/dist/integrations/github.js +0 -331
- package/dist/integrations/github.js.map +0 -1
- package/dist/integrations/google-tasks.js +0 -432
- package/dist/integrations/google-tasks.js.map +0 -1
- package/dist/mdns.js +0 -110
- package/dist/mdns.js.map +0 -1
- package/dist/notifications/channel.js +0 -83
- package/dist/notifications/channel.js.map +0 -1
- package/dist/notifications/channels/adapter.js +0 -55
- package/dist/notifications/channels/adapter.js.map +0 -1
- package/dist/notifications/channels/index.js +0 -6
- package/dist/notifications/channels/index.js.map +0 -1
- package/dist/notifications/channels/log.js +0 -29
- package/dist/notifications/channels/log.js.map +0 -1
- package/dist/notifications/email.js +0 -72
- package/dist/notifications/email.js.map +0 -1
- package/dist/notifications/engine.js +0 -198
- package/dist/notifications/engine.js.map +0 -1
- package/dist/notifications/index.js +0 -24
- package/dist/notifications/index.js.map +0 -1
- package/dist/notifications/phone.js +0 -48
- package/dist/notifications/phone.js.map +0 -1
- package/dist/notifications/sms.js +0 -65
- package/dist/notifications/sms.js.map +0 -1
- package/dist/notifications/types.js +0 -14
- package/dist/notifications/types.js.map +0 -1
- package/dist/notifications/webhook.js +0 -65
- package/dist/notifications/webhook.js.map +0 -1
- package/dist/resend/inbox.js +0 -199
- package/dist/resend/inbox.js.map +0 -1
- package/dist/resend/webhooks.js +0 -244
- package/dist/resend/webhooks.js.map +0 -1
- package/dist/search/browse.js +0 -225
- package/dist/search/browse.js.map +0 -1
- package/dist/search/perplexity.js +0 -41
- package/dist/search/perplexity.js.map +0 -1
- package/dist/slack/channels.js +0 -277
- package/dist/slack/channels.js.map +0 -1
- package/dist/slack/client.js +0 -468
- package/dist/slack/client.js.map +0 -1
- package/dist/slack/retry.js +0 -100
- package/dist/slack/retry.js.map +0 -1
- package/dist/slack/types.js +0 -52
- package/dist/slack/types.js.map +0 -1
- package/dist/slack/webhooks.js +0 -285
- package/dist/slack/webhooks.js.map +0 -1
- package/dist/stt/client.js +0 -66
- package/dist/stt/client.js.map +0 -1
- package/dist/stt/sidecar.js +0 -115
- package/dist/stt/sidecar.js.map +0 -1
- package/dist/tracing/bridge.js +0 -70
- package/dist/tracing/bridge.js.map +0 -1
- package/dist/tracing/correlation.js +0 -49
- package/dist/tracing/correlation.js.map +0 -1
- package/dist/tracing/index.js +0 -18
- package/dist/tracing/index.js.map +0 -1
- package/dist/tracing/init.js +0 -81
- package/dist/tracing/init.js.map +0 -1
- package/dist/tracing/instrument.js +0 -145
- package/dist/tracing/instrument.js.map +0 -1
- package/dist/tracing/middleware.js +0 -69
- package/dist/tracing/middleware.js.map +0 -1
- package/dist/tracing/tracer.js +0 -327
- package/dist/tracing/tracer.js.map +0 -1
- package/dist/tts/client.js +0 -48
- package/dist/tts/client.js.map +0 -1
- package/dist/tts/sidecar.js +0 -148
- package/dist/tts/sidecar.js.map +0 -1
- package/dist/twilio/call.js +0 -79
- package/dist/twilio/call.js.map +0 -1
- package/dist/vault/matcher.js +0 -197
- package/dist/vault/matcher.js.map +0 -1
- package/dist/vault/personal.js +0 -163
- package/dist/vault/personal.js.map +0 -1
- package/dist/vault/policy.js +0 -159
- package/dist/vault/policy.js.map +0 -1
- package/dist/vault/store.js +0 -122
- package/dist/vault/store.js.map +0 -1
- package/dist/vault/transfer.js +0 -188
- package/dist/vault/transfer.js.map +0 -1
- package/dist/volumes/index.js +0 -2
- package/dist/volumes/index.js.map +0 -1
- package/dist/volumes/manager.js +0 -462
- package/dist/volumes/manager.js.map +0 -1
- package/dist/volumes/types.js +0 -8
- package/dist/volumes/types.js.map +0 -1
- package/dist/webhooks/config.js +0 -214
- package/dist/webhooks/config.js.map +0 -1
- package/dist/webhooks/event-log.js +0 -132
- package/dist/webhooks/event-log.js.map +0 -1
- package/dist/webhooks/handler.js +0 -103
- package/dist/webhooks/handler.js.map +0 -1
- package/dist/webhooks/handlers.js +0 -231
- package/dist/webhooks/handlers.js.map +0 -1
- package/dist/webhooks/index.js +0 -33
- package/dist/webhooks/index.js.map +0 -1
- package/dist/webhooks/mount.js +0 -400
- package/dist/webhooks/mount.js.map +0 -1
- package/dist/webhooks/registry.js +0 -143
- package/dist/webhooks/registry.js.map +0 -1
- package/dist/webhooks/relay.js +0 -53
- package/dist/webhooks/relay.js.map +0 -1
- package/dist/webhooks/retry.js +0 -270
- package/dist/webhooks/retry.js.map +0 -1
- package/dist/webhooks/router.js +0 -290
- package/dist/webhooks/router.js.map +0 -1
- package/dist/webhooks/twilio.js +0 -129
- package/dist/webhooks/twilio.js.map +0 -1
- package/dist/webhooks/types.js +0 -8
- package/dist/webhooks/types.js.map +0 -1
- package/dist/webhooks/verify.js +0 -154
- package/dist/webhooks/verify.js.map +0 -1
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Brain v2 migration — moves from 30+ top-level directories to 3:
|
|
3
|
+
* log/ ← append-only JSONL (memory, ops, metrics, ledger)
|
|
4
|
+
* files/ ← everything else (knowledge, identity, content, etc.)
|
|
5
|
+
* .config/ ← settings, access, locked paths
|
|
6
|
+
*
|
|
7
|
+
* Safe to run multiple times. Moves directories, doesn't copy.
|
|
8
|
+
* Creates symlinks from old paths to new locations for backward compat.
|
|
9
|
+
*/
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { rename, mkdir, cp, access } from "node:fs/promises";
|
|
12
|
+
import { BRAIN_DIR, LOG_DIR, FILES_DIR, CONFIG_DIR, isBrainV2 } from "./paths.js";
|
|
13
|
+
/** Directories that contain append-only JSONL data → move to log/ */
|
|
14
|
+
const TO_LOG = ["memory", "ops", "metrics", "ledger"];
|
|
15
|
+
/** Directories that contain searchable files → move to files/ */
|
|
16
|
+
const TO_FILES = [
|
|
17
|
+
"identity", "knowledge", "content", "operations", "skills",
|
|
18
|
+
"templates", "contacts", "calendar", "scheduling", "training",
|
|
19
|
+
"library", "dictionary", "browser", "registry", "channels",
|
|
20
|
+
"runtime", "calibration", "compliance", "membrane", "inference",
|
|
21
|
+
"db", "compost",
|
|
22
|
+
];
|
|
23
|
+
/** Files/dirs that move to .config/ */
|
|
24
|
+
const TO_CONFIG = [
|
|
25
|
+
"settings.json", ".locked", ".access", ".core", ".ui",
|
|
26
|
+
"vault.policy.yaml",
|
|
27
|
+
];
|
|
28
|
+
/** Directories that stay at top level (runtime state, not brain data) */
|
|
29
|
+
const STAYS = ["agents", "sessions", "vault", "volumes", "webhooks", "files"];
|
|
30
|
+
async function exists(path) {
|
|
31
|
+
try {
|
|
32
|
+
await access(path);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function moveIfExists(src, dest) {
|
|
40
|
+
if (!(await exists(src)))
|
|
41
|
+
return false;
|
|
42
|
+
if (await exists(dest)) {
|
|
43
|
+
// Dest already exists — merge by copying contents
|
|
44
|
+
try {
|
|
45
|
+
await cp(src, dest, { recursive: true, force: false, errorOnExist: false });
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// If cp fails, skip — don't lose data
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
// Ensure parent exists
|
|
54
|
+
const parent = join(dest, "..");
|
|
55
|
+
await mkdir(parent, { recursive: true });
|
|
56
|
+
try {
|
|
57
|
+
await rename(src, dest);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Cross-device rename — fall back to copy
|
|
62
|
+
try {
|
|
63
|
+
await cp(src, dest, { recursive: true });
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Migrate a brain directory from legacy layout to v2.
|
|
73
|
+
* Safe to run multiple times — skips already-migrated items.
|
|
74
|
+
*/
|
|
75
|
+
export async function migrateBrainToV2() {
|
|
76
|
+
const result = { migrated: [], skipped: [], errors: [], alreadyV2: false };
|
|
77
|
+
if (isBrainV2()) {
|
|
78
|
+
result.alreadyV2 = true;
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
// Create v2 directories
|
|
82
|
+
await mkdir(LOG_DIR, { recursive: true });
|
|
83
|
+
await mkdir(FILES_DIR, { recursive: true });
|
|
84
|
+
await mkdir(CONFIG_DIR, { recursive: true });
|
|
85
|
+
// Move log directories
|
|
86
|
+
for (const dir of TO_LOG) {
|
|
87
|
+
const src = join(BRAIN_DIR, dir);
|
|
88
|
+
const dest = join(LOG_DIR, dir);
|
|
89
|
+
try {
|
|
90
|
+
if (await moveIfExists(src, dest)) {
|
|
91
|
+
result.migrated.push(`${dir} → log/${dir}`);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
result.skipped.push(dir);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
result.errors.push(`${dir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Move files directories
|
|
102
|
+
for (const dir of TO_FILES) {
|
|
103
|
+
const src = join(BRAIN_DIR, dir);
|
|
104
|
+
const dest = join(FILES_DIR, dir);
|
|
105
|
+
try {
|
|
106
|
+
if (await moveIfExists(src, dest)) {
|
|
107
|
+
result.migrated.push(`${dir} → files/${dir}`);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
result.skipped.push(dir);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
result.errors.push(`${dir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Move config items
|
|
118
|
+
for (const item of TO_CONFIG) {
|
|
119
|
+
const src = join(BRAIN_DIR, item);
|
|
120
|
+
const dest = join(CONFIG_DIR, item);
|
|
121
|
+
try {
|
|
122
|
+
if (await moveIfExists(src, dest)) {
|
|
123
|
+
result.migrated.push(`${item} → .config/${item}`);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
result.skipped.push(item);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
result.errors.push(`${item}: ${err instanceof Error ? err.message : String(err)}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Write a marker so isBrainV2() detects the migration
|
|
134
|
+
// (LOG_DIR existence is the marker — it was just created)
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=brain-migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brain-migrate.js","sourceRoot":"","sources":["../../src/lib/brain-migrate.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/paths.d.ts
CHANGED
|
@@ -5,7 +5,34 @@
|
|
|
5
5
|
* Packages are code only, no data ever. The brain lives outside the package,
|
|
6
6
|
* configured via CORE_BRAIN_DIR (or DASH_BRAIN_DIR) environment variable.
|
|
7
7
|
* Default: process.cwd() + "brain" for backward compatibility.
|
|
8
|
+
*
|
|
9
|
+
* Brain structure (v2 — simplified):
|
|
10
|
+
* brain/
|
|
11
|
+
* log/ ← append-only JSONL. The trail. Never rewrite.
|
|
12
|
+
* files/ ← everything else. Searchable. Flat or shallow.
|
|
13
|
+
* .config/ ← settings, access policies, locked paths. Plumbing.
|
|
14
|
+
*
|
|
15
|
+
* Legacy paths (memory/, ops/, knowledge/, identity/, etc.) are resolved
|
|
16
|
+
* with fallback for backward compatibility during migration.
|
|
8
17
|
*/
|
|
9
18
|
/** Absolute path to the brain data directory. */
|
|
10
19
|
export declare const BRAIN_DIR: string;
|
|
20
|
+
/** Append-only JSONL — the audit trail, memory, activity, metrics. */
|
|
21
|
+
export declare const LOG_DIR: string;
|
|
22
|
+
/** Everything else — notes, research, identity, templates, contacts. Searchable. */
|
|
23
|
+
export declare const FILES_DIR: string;
|
|
24
|
+
/** Settings, access policies, locked paths. Plumbing. */
|
|
25
|
+
export declare const CONFIG_DIR: string;
|
|
26
|
+
/**
|
|
27
|
+
* Resolve a brain subdirectory, checking v2 structure first, falling back to legacy.
|
|
28
|
+
* Use this for any path that might exist under old OR new layout.
|
|
29
|
+
*
|
|
30
|
+
* Example: resolveBrainDir("memory") → brain/log (if migrated) or brain/memory (legacy)
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveBrainDir(subdir: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Detect whether this brain uses v2 structure.
|
|
35
|
+
* True if brain/log/ exists. False means legacy layout.
|
|
36
|
+
*/
|
|
37
|
+
export declare function isBrainV2(): boolean;
|
|
11
38
|
//# sourceMappingURL=paths.d.ts.map
|
package/dist/lib/paths.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,iDAAiD;AACjD,eAAO,MAAM,SAAS,EAAE,MAEvB,CAAC;AAIF,sEAAsE;AACtE,eAAO,MAAM,OAAO,EAAE,MAA+B,CAAC;AAEtD,oFAAoF;AACpF,eAAO,MAAM,SAAS,EAAE,MAAiC,CAAC;AAE1D,yDAAyD;AACzD,eAAO,MAAM,UAAU,EAAE,MAAmC,CAAC;AAe7D;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAqBtD;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC"}
|
package/dist/lib/paths.js
CHANGED
|
@@ -5,9 +5,74 @@
|
|
|
5
5
|
* Packages are code only, no data ever. The brain lives outside the package,
|
|
6
6
|
* configured via CORE_BRAIN_DIR (or DASH_BRAIN_DIR) environment variable.
|
|
7
7
|
* Default: process.cwd() + "brain" for backward compatibility.
|
|
8
|
+
*
|
|
9
|
+
* Brain structure (v2 — simplified):
|
|
10
|
+
* brain/
|
|
11
|
+
* log/ ← append-only JSONL. The trail. Never rewrite.
|
|
12
|
+
* files/ ← everything else. Searchable. Flat or shallow.
|
|
13
|
+
* .config/ ← settings, access policies, locked paths. Plumbing.
|
|
14
|
+
*
|
|
15
|
+
* Legacy paths (memory/, ops/, knowledge/, identity/, etc.) are resolved
|
|
16
|
+
* with fallback for backward compatibility during migration.
|
|
8
17
|
*/
|
|
9
18
|
import { resolve, join } from "node:path";
|
|
19
|
+
import { existsSync } from "node:fs";
|
|
10
20
|
import { resolveEnv } from "../instance.js";
|
|
11
21
|
/** Absolute path to the brain data directory. */
|
|
12
22
|
export const BRAIN_DIR = resolve(resolveEnv("BRAIN_DIR") ?? join(process.cwd(), "brain"));
|
|
23
|
+
// ── v2 structure ──────────────────────────────────────────────────────────────
|
|
24
|
+
/** Append-only JSONL — the audit trail, memory, activity, metrics. */
|
|
25
|
+
export const LOG_DIR = join(BRAIN_DIR, "log");
|
|
26
|
+
/** Everything else — notes, research, identity, templates, contacts. Searchable. */
|
|
27
|
+
export const FILES_DIR = join(BRAIN_DIR, "files");
|
|
28
|
+
/** Settings, access policies, locked paths. Plumbing. */
|
|
29
|
+
export const CONFIG_DIR = join(BRAIN_DIR, ".config");
|
|
30
|
+
// ── Legacy path resolution ────────────────────────────────────────────────────
|
|
31
|
+
/** Map of legacy directory names to their v2 parent. */
|
|
32
|
+
const LEGACY_TO_LOG = ["memory", "ops", "metrics", "ledger"];
|
|
33
|
+
const LEGACY_TO_FILES = [
|
|
34
|
+
"identity", "knowledge", "content", "operations", "skills",
|
|
35
|
+
"templates", "contacts", "calendar", "scheduling", "training",
|
|
36
|
+
"agents", "library", "dictionary", "browser", "sessions",
|
|
37
|
+
"registry", "channels", "vault", "files", "runtime",
|
|
38
|
+
"calibration", "compliance", "membrane", "inference", "db",
|
|
39
|
+
"compost",
|
|
40
|
+
];
|
|
41
|
+
/**
|
|
42
|
+
* Resolve a brain subdirectory, checking v2 structure first, falling back to legacy.
|
|
43
|
+
* Use this for any path that might exist under old OR new layout.
|
|
44
|
+
*
|
|
45
|
+
* Example: resolveBrainDir("memory") → brain/log (if migrated) or brain/memory (legacy)
|
|
46
|
+
*/
|
|
47
|
+
export function resolveBrainDir(subdir) {
|
|
48
|
+
// Check v2 structure first
|
|
49
|
+
if (LEGACY_TO_LOG.includes(subdir)) {
|
|
50
|
+
const v2 = join(LOG_DIR, subdir);
|
|
51
|
+
if (existsSync(v2))
|
|
52
|
+
return v2;
|
|
53
|
+
// Fall back to legacy flat path
|
|
54
|
+
const legacy = join(BRAIN_DIR, subdir);
|
|
55
|
+
if (existsSync(legacy))
|
|
56
|
+
return legacy;
|
|
57
|
+
return v2; // default to v2 for new files
|
|
58
|
+
}
|
|
59
|
+
if (LEGACY_TO_FILES.includes(subdir)) {
|
|
60
|
+
const v2 = join(FILES_DIR, subdir);
|
|
61
|
+
if (existsSync(v2))
|
|
62
|
+
return v2;
|
|
63
|
+
const legacy = join(BRAIN_DIR, subdir);
|
|
64
|
+
if (existsSync(legacy))
|
|
65
|
+
return legacy;
|
|
66
|
+
return v2;
|
|
67
|
+
}
|
|
68
|
+
// Unknown subdir — check under brain/ directly
|
|
69
|
+
return join(BRAIN_DIR, subdir);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Detect whether this brain uses v2 structure.
|
|
73
|
+
* True if brain/log/ exists. False means legacy layout.
|
|
74
|
+
*/
|
|
75
|
+
export function isBrainV2() {
|
|
76
|
+
return existsSync(LOG_DIR);
|
|
77
|
+
}
|
|
13
78
|
//# sourceMappingURL=paths.js.map
|
package/dist/lib/paths.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,iDAAiD;AACjD,MAAM,CAAC,MAAM,SAAS,GAAW,OAAO,CACtC,UAAU,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CACxD,CAAC;AAEF,iFAAiF;AAEjF,sEAAsE;AACtE,MAAM,CAAC,MAAM,OAAO,GAAW,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AAEtD,oFAAoF;AACpF,MAAM,CAAC,MAAM,SAAS,GAAW,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAE1D,yDAAyD;AACzD,MAAM,CAAC,MAAM,UAAU,GAAW,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;AAE7D,iFAAiF;AAEjF,wDAAwD;AACxD,MAAM,aAAa,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAC;AACtE,MAAM,eAAe,GAAG;IACtB,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ;IAC1D,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU;IAC7D,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU;IACxD,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS;IACnD,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,IAAI;IAC1D,SAAS;CACD,CAAC;AAEX;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,2BAA2B;IAC3B,IAAK,aAAmC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1D,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACjC,IAAI,UAAU,CAAC,EAAE,CAAC;YAAE,OAAO,EAAE,CAAC;QAC9B,gCAAgC;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACvC,IAAI,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,MAAM,CAAC;QACtC,OAAO,EAAE,CAAC,CAAC,8BAA8B;IAC3C,CAAC;IAED,IAAK,eAAqC,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5D,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACnC,IAAI,UAAU,CAAC,EAAE,CAAC;YAAE,OAAO,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACvC,IAAI,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,MAAM,CAAC;QACtC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,+CAA+C;IAC/C,OAAO,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM call log — append-only JSONL receipt for every LLM call.
|
|
3
|
+
*
|
|
4
|
+
* Records the mechanical state of each call: which provider, which model,
|
|
5
|
+
* how it was resolved, how long it took. No prompts, no responses, no content.
|
|
6
|
+
* Just the state of the machine at the time of the turn.
|
|
7
|
+
*
|
|
8
|
+
* Writes to brain/memory/llm-calls.jsonl (data lives in brain, not code).
|
|
9
|
+
*/
|
|
10
|
+
export interface LlmCallEntry {
|
|
11
|
+
/** ISO timestamp */
|
|
12
|
+
ts: string;
|
|
13
|
+
/** "stream" or "complete" */
|
|
14
|
+
mode: "stream" | "complete";
|
|
15
|
+
/** Provider that actually handled the call */
|
|
16
|
+
provider: string;
|
|
17
|
+
/** Model that was actually used */
|
|
18
|
+
model: string;
|
|
19
|
+
/** How the provider was resolved: "settings", "env", "taskRoute", "fallback", "privateMode" */
|
|
20
|
+
routeSource?: string;
|
|
21
|
+
/** Task type if routed via taskRoutes */
|
|
22
|
+
taskType?: string;
|
|
23
|
+
/** Agent ID if this call was made by a spawned agent */
|
|
24
|
+
agentId?: string;
|
|
25
|
+
/** Duration in ms */
|
|
26
|
+
durationMs: number;
|
|
27
|
+
/** Estimated input tokens (chars/4) */
|
|
28
|
+
inputTokens?: number;
|
|
29
|
+
/** Estimated output tokens (chars/4) */
|
|
30
|
+
outputTokens?: number;
|
|
31
|
+
/** Whether the call succeeded */
|
|
32
|
+
ok: boolean;
|
|
33
|
+
/** Error message on failure (no stack traces) */
|
|
34
|
+
error?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Append a call receipt to the log. Fire-and-forget — never throws.
|
|
38
|
+
*/
|
|
39
|
+
export declare function logLlmCall(entry: LlmCallEntry): Promise<void>;
|
|
40
|
+
//# sourceMappingURL=call-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-log.d.ts","sourceRoot":"","sources":["../../src/llm/call-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAYH,MAAM,WAAW,YAAY;IAC3B,oBAAoB;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,6BAA6B;IAC7B,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC5B,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,+FAA+F;IAC/F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qBAAqB;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,EAAE,EAAE,OAAO,CAAC;IACZ,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAanE"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM call log — append-only JSONL receipt for every LLM call.
|
|
3
|
+
*
|
|
4
|
+
* Records the mechanical state of each call: which provider, which model,
|
|
5
|
+
* how it was resolved, how long it took. No prompts, no responses, no content.
|
|
6
|
+
* Just the state of the machine at the time of the turn.
|
|
7
|
+
*
|
|
8
|
+
* Writes to brain/memory/llm-calls.jsonl (data lives in brain, not code).
|
|
9
|
+
*/
|
|
10
|
+
import { appendFile, mkdir } from "node:fs/promises";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { BRAIN_DIR } from "../lib/paths.js";
|
|
13
|
+
import { createLogger } from "../utils/logger.js";
|
|
14
|
+
const log = createLogger("llm.call-log");
|
|
15
|
+
const LOG_PATH = join(BRAIN_DIR, "memory", "llm-calls.jsonl");
|
|
16
|
+
let ensuredDir = false;
|
|
17
|
+
/**
|
|
18
|
+
* Append a call receipt to the log. Fire-and-forget — never throws.
|
|
19
|
+
*/
|
|
20
|
+
export async function logLlmCall(entry) {
|
|
21
|
+
try {
|
|
22
|
+
if (!ensuredDir) {
|
|
23
|
+
await mkdir(join(BRAIN_DIR, "memory"), { recursive: true });
|
|
24
|
+
ensuredDir = true;
|
|
25
|
+
}
|
|
26
|
+
const line = JSON.stringify(entry) + "\n";
|
|
27
|
+
await appendFile(LOG_PATH, line, "utf-8");
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
log.warn("Failed to write call log", {
|
|
31
|
+
error: err instanceof Error ? err.message : String(err),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=call-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-log.js","sourceRoot":"","sources":["../../src/llm/call-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,GAAG,GAAG,YAAY,CAAC,cAAc,CAAC,CAAC;AAEzC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC;AAC9D,IAAI,UAAU,GAAG,KAAK,CAAC;AA6BvB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAmB;IAClD,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5D,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;QAC1C,MAAM,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,IAAI,CAAC,0BAA0B,EAAE;YACnC,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
|
package/dist/llm/complete.d.ts
CHANGED
|
@@ -14,6 +14,12 @@ export interface CompleteChatOptions {
|
|
|
14
14
|
noCache?: boolean;
|
|
15
15
|
/** Override default TTL for this request (ms). */
|
|
16
16
|
cacheTTLMs?: number;
|
|
17
|
+
/** How the provider/model was resolved (for call log). */
|
|
18
|
+
routeSource?: string;
|
|
19
|
+
/** Task type if routed via taskRoutes (for call log). */
|
|
20
|
+
taskType?: string;
|
|
21
|
+
/** Agent ID if called by a spawned agent (for call log). */
|
|
22
|
+
agentId?: string;
|
|
17
23
|
}
|
|
18
24
|
/**
|
|
19
25
|
* Non-streaming chat completion. Returns the full assistant response as a string.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../src/llm/complete.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../src/llm/complete.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAYzD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,YAAY,CAAC;IACvB,mCAAmC;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAGhF"}
|
package/dist/llm/complete.js
CHANGED
|
@@ -11,6 +11,7 @@ import { withRetry } from "./retry.js";
|
|
|
11
11
|
import { rehydrateResponse } from "./redact.js";
|
|
12
12
|
import { createLogger } from "../utils/logger.js";
|
|
13
13
|
import { recordLlmRequest } from "../metrics/collector.js";
|
|
14
|
+
import { logLlmCall } from "./call-log.js";
|
|
14
15
|
const log = createLogger("llm");
|
|
15
16
|
/**
|
|
16
17
|
* Non-streaming chat completion. Returns the full assistant response as a string.
|
|
@@ -57,6 +58,12 @@ async function completeChatUncached(options) {
|
|
|
57
58
|
const durationMs = Math.round(performance.now() - startMs);
|
|
58
59
|
const outputTokens = Math.ceil(result.length / 4);
|
|
59
60
|
recordLlmRequest(options.provider, model, durationMs, inputTokens, outputTokens, true);
|
|
61
|
+
logLlmCall({
|
|
62
|
+
ts: new Date().toISOString(), mode: "complete",
|
|
63
|
+
provider: options.provider, model,
|
|
64
|
+
routeSource: options.routeSource, taskType: options.taskType, agentId: options.agentId,
|
|
65
|
+
durationMs, inputTokens, outputTokens, ok: true,
|
|
66
|
+
});
|
|
60
67
|
return result;
|
|
61
68
|
}
|
|
62
69
|
catch (err) {
|
|
@@ -81,11 +88,31 @@ async function completeChatUncached(options) {
|
|
|
81
88
|
// Also record the original provider's failure
|
|
82
89
|
const failDurationMs = Math.round(fallbackStartMs - startMs);
|
|
83
90
|
recordLlmRequest(options.provider, model, failDurationMs, inputTokens, 0, false);
|
|
91
|
+
// Log both: the failed cloud call and the successful fallback
|
|
92
|
+
logLlmCall({
|
|
93
|
+
ts: new Date().toISOString(), mode: "complete",
|
|
94
|
+
provider: options.provider, model,
|
|
95
|
+
routeSource: options.routeSource, taskType: options.taskType, agentId: options.agentId,
|
|
96
|
+
durationMs: failDurationMs, inputTokens, ok: false, error: "credits_exhausted",
|
|
97
|
+
});
|
|
98
|
+
logLlmCall({
|
|
99
|
+
ts: new Date().toISOString(), mode: "complete",
|
|
100
|
+
provider: "ollama", model: ollama.defaultUtilityModel,
|
|
101
|
+
routeSource: "fallback", taskType: options.taskType, agentId: options.agentId,
|
|
102
|
+
durationMs: fallbackDurationMs, inputTokens, outputTokens: fallbackOutputTokens, ok: true,
|
|
103
|
+
});
|
|
84
104
|
return fallbackResult;
|
|
85
105
|
}
|
|
86
106
|
}
|
|
87
107
|
const durationMs = Math.round(performance.now() - startMs);
|
|
88
108
|
recordLlmRequest(options.provider, model, durationMs, inputTokens, 0, false);
|
|
109
|
+
logLlmCall({
|
|
110
|
+
ts: new Date().toISOString(), mode: "complete",
|
|
111
|
+
provider: options.provider, model,
|
|
112
|
+
routeSource: options.routeSource, taskType: options.taskType, agentId: options.agentId,
|
|
113
|
+
durationMs, inputTokens, ok: false,
|
|
114
|
+
error: err instanceof Error ? err.message : String(err),
|
|
115
|
+
});
|
|
89
116
|
throw err;
|
|
90
117
|
}
|
|
91
118
|
}
|
package/dist/llm/complete.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"complete.js","sourceRoot":"","sources":["../../src/llm/complete.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"complete.js","sourceRoot":"","sources":["../../src/llm/complete.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp-server.js
CHANGED
|
@@ -24,9 +24,10 @@ import { sendAlert } from "./alert.js";
|
|
|
24
24
|
import { Crystallizer, scoreEntry } from "./crystallizer.js";
|
|
25
25
|
import { createCredentialStore } from "./credentials/store.js";
|
|
26
26
|
import { readSessionKey, isDpapiAvailable } from "./lib/dpapi.js";
|
|
27
|
+
import { BrainRAG } from "./search/brain-rag.js";
|
|
27
28
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
28
|
-
import { BRAIN_DIR } from "./lib/paths.js";
|
|
29
|
-
const MEMORY_DIR =
|
|
29
|
+
import { BRAIN_DIR, resolveBrainDir } from "./lib/paths.js";
|
|
30
|
+
const MEMORY_DIR = resolveBrainDir("memory");
|
|
30
31
|
/** Log to stderr so stdout stays clean for MCP protocol. */
|
|
31
32
|
function log(msg) {
|
|
32
33
|
process.stderr.write(`[core-brain-mcp] ${msg}\n`);
|
|
@@ -108,6 +109,16 @@ async function main() {
|
|
|
108
109
|
});
|
|
109
110
|
await crystallizer.init();
|
|
110
111
|
log(`Open loops loaded: ${crystallizer.list("open").length} active`);
|
|
112
|
+
// 6b. Initialize Brain RAG (semantic file search)
|
|
113
|
+
const mcpRag = new BrainRAG();
|
|
114
|
+
await mcpRag.load(); // Load existing embeddings (fast, no Ollama needed)
|
|
115
|
+
log(`Brain RAG loaded: ${mcpRag.ready ? "ready" : "empty"}`);
|
|
116
|
+
// Background index — catch up on any changed files
|
|
117
|
+
mcpRag.indexAll().then((r) => {
|
|
118
|
+
log(`Brain RAG index: ${r.indexed} indexed, ${r.skipped} skipped, ${r.errors} errors`);
|
|
119
|
+
}).catch((err) => {
|
|
120
|
+
log(`Brain RAG index failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
121
|
+
});
|
|
111
122
|
// 6. Create MCP server
|
|
112
123
|
const mcp = new McpServer({
|
|
113
124
|
name: "core-brain",
|
|
@@ -259,6 +270,111 @@ async function main() {
|
|
|
259
270
|
};
|
|
260
271
|
}
|
|
261
272
|
}));
|
|
273
|
+
mcp.tool("files_search", "Search brain files (notes, research, identity, templates, protocols — everything except logs) by keyword. Returns matching filenames with context snippets.", {
|
|
274
|
+
query: z.string().min(1).max(500).describe("Search query — keywords to find in brain files"),
|
|
275
|
+
max: z.number().int().min(1).max(20).optional().describe("Max results (default 10)"),
|
|
276
|
+
}, async ({ query, max }) => runWithAuditContext({ caller: "mcp:files_search", channel: "mcp" }, async () => {
|
|
277
|
+
const maxResults = max ?? 10;
|
|
278
|
+
const terms = query.toLowerCase().split(/\s+/).filter((t) => t.length > 1);
|
|
279
|
+
if (terms.length === 0) {
|
|
280
|
+
return { content: [{ type: "text", text: "No search terms provided." }] };
|
|
281
|
+
}
|
|
282
|
+
// Scan all non-log directories for readable files (md, yaml, yml, json, txt)
|
|
283
|
+
const searchExts = new Set([".md", ".yaml", ".yml", ".json", ".txt", ".jsonl"]);
|
|
284
|
+
const skipDirs = new Set(["log", ".config", "ops", "metrics", ".obsidian", ".git", "node_modules"]);
|
|
285
|
+
const hits = [];
|
|
286
|
+
async function scanDir(dir, rel) {
|
|
287
|
+
let entries;
|
|
288
|
+
try {
|
|
289
|
+
entries = await readdir(dir);
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
for (const name of entries) {
|
|
295
|
+
if (name.startsWith(".") && rel === "") {
|
|
296
|
+
// Skip hidden dirs at top level except .config
|
|
297
|
+
if (skipDirs.has(name))
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
if (skipDirs.has(name))
|
|
301
|
+
continue;
|
|
302
|
+
const full = join(dir, name);
|
|
303
|
+
const childRel = rel ? `${rel}/${name}` : name;
|
|
304
|
+
try {
|
|
305
|
+
const s = await stat(full);
|
|
306
|
+
if (s.isDirectory()) {
|
|
307
|
+
// Don't recurse into JSONL-heavy log dirs
|
|
308
|
+
if (name === "memory" || name === "logs" || name === "tasks" || name === "daily" || name === "hourly")
|
|
309
|
+
continue;
|
|
310
|
+
await scanDir(full, childRel);
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
const ext = name.substring(name.lastIndexOf(".")).toLowerCase();
|
|
314
|
+
if (!searchExts.has(ext))
|
|
315
|
+
continue;
|
|
316
|
+
if (isLocked(childRel))
|
|
317
|
+
continue;
|
|
318
|
+
// Skip large JSONL files (those are log data, not knowledge)
|
|
319
|
+
if (ext === ".jsonl" && s.size > 100_000)
|
|
320
|
+
continue;
|
|
321
|
+
const content = await readBrainFile(full);
|
|
322
|
+
const lower = content.toLowerCase();
|
|
323
|
+
let score = 0;
|
|
324
|
+
for (const term of terms) {
|
|
325
|
+
const idx = lower.indexOf(term);
|
|
326
|
+
if (idx !== -1) {
|
|
327
|
+
score++;
|
|
328
|
+
// Bonus for title/filename match
|
|
329
|
+
if (name.toLowerCase().includes(term))
|
|
330
|
+
score += 2;
|
|
331
|
+
}
|
|
332
|
+
// Match against full relative path (catches parent directory names)
|
|
333
|
+
if (childRel.toLowerCase().includes(term))
|
|
334
|
+
score += 2;
|
|
335
|
+
}
|
|
336
|
+
if (score > 0) {
|
|
337
|
+
// Extract a snippet around the first match
|
|
338
|
+
const firstTerm = terms.find((t) => lower.includes(t));
|
|
339
|
+
const matchIdx = lower.indexOf(firstTerm);
|
|
340
|
+
const start = Math.max(0, matchIdx - 80);
|
|
341
|
+
const end = Math.min(content.length, matchIdx + 120);
|
|
342
|
+
const snippet = (start > 0 ? "..." : "") +
|
|
343
|
+
content.substring(start, end).replace(/\n/g, " ").trim() +
|
|
344
|
+
(end < content.length ? "..." : "");
|
|
345
|
+
hits.push({ relPath: childRel, score, snippet });
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
catch {
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
await scanDir(BRAIN_DIR, "");
|
|
355
|
+
// If keyword search found nothing, try semantic search via RAG
|
|
356
|
+
if (hits.length === 0 && mcpRag?.ready) {
|
|
357
|
+
try {
|
|
358
|
+
const ragResults = await mcpRag.query(query, maxResults);
|
|
359
|
+
if (ragResults.length > 0) {
|
|
360
|
+
const result = ragResults.map((r) => `📄 ${r.filePath} (semantic score: ${r.score.toFixed(3)}, section: ${r.heading})${r.siblings ? `\n Also in directory: ${r.siblings.join(", ")}` : ""}`).join("\n\n");
|
|
361
|
+
return {
|
|
362
|
+
content: [{ type: "text", text: `Keyword search found nothing. Semantic search found ${ragResults.length} file(s):\n\n${result}` }],
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
catch { /* semantic search failed — fall through */ }
|
|
367
|
+
}
|
|
368
|
+
if (hits.length === 0) {
|
|
369
|
+
return { content: [{ type: "text", text: `No files matched: "${query}"` }] };
|
|
370
|
+
}
|
|
371
|
+
hits.sort((a, b) => b.score - a.score);
|
|
372
|
+
const top = hits.slice(0, maxResults);
|
|
373
|
+
const result = top.map((h) => `📄 ${h.relPath} (score: ${h.score})\n ${h.snippet}`).join("\n\n");
|
|
374
|
+
return {
|
|
375
|
+
content: [{ type: "text", text: `Found ${hits.length} file(s) matching "${query}":\n\n${result}` }],
|
|
376
|
+
};
|
|
377
|
+
}));
|
|
262
378
|
mcp.tool("get_settings", "Return safe subset of Core settings (no keys or secrets)", {}, async () => {
|
|
263
379
|
const s = getSettings();
|
|
264
380
|
const safe = {
|