@rubytech/create-realagent 1.0.839 → 1.0.842
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/package.json +1 -1
- package/payload/platform/lib/account-enumeration/dist/__tests__/enumerate.test.d.ts +2 -0
- package/payload/platform/lib/account-enumeration/dist/__tests__/enumerate.test.d.ts.map +1 -0
- package/payload/platform/lib/account-enumeration/dist/__tests__/enumerate.test.js +88 -0
- package/payload/platform/lib/account-enumeration/dist/__tests__/enumerate.test.js.map +1 -0
- package/payload/platform/lib/account-enumeration/dist/index.d.ts +23 -0
- package/payload/platform/lib/account-enumeration/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/account-enumeration/dist/index.js +96 -0
- package/payload/platform/lib/account-enumeration/dist/index.js.map +1 -0
- package/payload/platform/lib/account-enumeration/src/__tests__/enumerate.test.ts +94 -0
- package/payload/platform/lib/account-enumeration/src/index.ts +96 -0
- package/payload/platform/lib/account-enumeration/tsconfig.json +8 -0
- package/payload/platform/lib/graph-write/dist/__tests__/account-id-gate.test.d.ts +2 -0
- package/payload/platform/lib/graph-write/dist/__tests__/account-id-gate.test.d.ts.map +1 -0
- package/payload/platform/lib/graph-write/dist/__tests__/account-id-gate.test.js +165 -0
- package/payload/platform/lib/graph-write/dist/__tests__/account-id-gate.test.js.map +1 -0
- package/payload/platform/lib/graph-write/dist/__tests__/action-provenance-gate.test.js +15 -5
- package/payload/platform/lib/graph-write/dist/__tests__/action-provenance-gate.test.js.map +1 -1
- package/payload/platform/lib/graph-write/dist/index.d.ts +12 -0
- package/payload/platform/lib/graph-write/dist/index.d.ts.map +1 -1
- package/payload/platform/lib/graph-write/dist/index.js +25 -0
- package/payload/platform/lib/graph-write/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-write/src/__tests__/account-id-gate.test.ts +189 -0
- package/payload/platform/lib/graph-write/src/__tests__/action-provenance-gate.test.ts +16 -5
- package/payload/platform/lib/graph-write/src/index.ts +45 -1
- package/payload/platform/package.json +2 -2
- package/payload/platform/plugins/docs/references/attachments.md +2 -2
- package/payload/platform/plugins/docs/references/internals.md +1 -1
- package/payload/platform/plugins/docs/references/platform.md +1 -1
- package/payload/platform/plugins/docs/references/troubleshooting.md +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/uuid.js +7 -7
- package/payload/platform/plugins/memory/mcp/dist/lib/uuid.js.map +1 -1
- package/payload/platform/plugins/whatsapp/PLUGIN.md +1 -1
- package/payload/platform/templates/agents/admin/IDENTITY.md +4 -0
- package/payload/server/adminuser-self-heal-RY4NFCI7.js +45 -0
- package/payload/server/chunk-2YG3AYAH.js +1508 -0
- package/payload/server/chunk-7DFOKDNM.js +2098 -0
- package/payload/server/chunk-CJWFM3WX.js +2098 -0
- package/payload/server/chunk-D5U4XQ66.js +656 -0
- package/payload/server/chunk-DJXPAH7T.js +1480 -0
- package/payload/server/chunk-DTWW35TK.js +667 -0
- package/payload/server/chunk-HTYXRFT6.js +727 -0
- package/payload/server/chunk-NPVEOM3D.js +1508 -0
- package/payload/server/chunk-QGM4M3NI.js +37 -0
- package/payload/server/chunk-S27QCBFQ.js +10071 -0
- package/payload/server/chunk-T2MQIKBT.js +10001 -0
- package/payload/server/chunk-TS6CKCGU.js +727 -0
- package/payload/server/chunk-XECKT3YB.js +10071 -0
- package/payload/server/client-pool-2WQ2Q3TF.js +32 -0
- package/payload/server/client-pool-M25CGILI.js +32 -0
- package/payload/server/client-pool-SMWCZMZG.js +32 -0
- package/payload/server/cloudflare-task-tracker-GQFKLY62.js +20 -0
- package/payload/server/cloudflare-task-tracker-NQK7A2EQ.js +20 -0
- package/payload/server/cloudflare-task-tracker-O4ZA4TAS.js +20 -0
- package/payload/server/cloudflare-task-tracker-XFGXO7ZV.js +20 -0
- package/payload/server/maxy-edge.js +3 -4
- package/payload/server/public/assets/{Checkbox-Bq6ORjz2.js → Checkbox-aCc0UGp3.js} +1 -1
- package/payload/server/public/assets/{admin-CstEkw-G.js → admin-CvwOOG4D.js} +2 -2
- package/payload/server/public/assets/data-DsItQm8c.js +1 -0
- package/payload/server/public/assets/graph-C-HOmfmU.js +1 -0
- package/payload/server/public/assets/{jsx-runtime-DidQeNoZ.css → jsx-runtime-BKoartnM.css} +1 -1
- package/payload/server/public/assets/{page-CFWoVkgV.js → page-D7LchjvY.js} +1 -1
- package/payload/server/public/assets/{page-Bpi_jPw6.js → page-DTmTvkNo.js} +1 -1
- package/payload/server/public/assets/{public-BWMwq5Jj.js → public-Br9YjNs_.js} +2 -2
- package/payload/server/public/assets/{useAdminFetch-B93ig7ef.js → useAdminFetch-BgDL3JGd.js} +1 -1
- package/payload/server/public/assets/{useVoiceRecorder-Cb0nAtOo.js → useVoiceRecorder-Bx903Mk1.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +8 -8
- package/payload/server/public/public.html +5 -5
- package/payload/server/server.js +81 -67
- package/payload/platform/neo4j/migrations/001-backfill-scope.cypher +0 -30
- package/payload/platform/neo4j/migrations/002-project-public-agents.ts +0 -191
- package/payload/platform/neo4j/migrations/003-person-name-eradicate.cypher +0 -24
- package/payload/platform/neo4j/migrations/004-project-admin-agent.ts +0 -348
- package/payload/platform/neo4j/migrations/004-prune-alien-accounts.ts +0 -133
- package/payload/platform/neo4j/migrations/005-removed-review-feature.ts +0 -102
- package/payload/platform/neo4j/migrations/006-prune-bogus-whatsapp-persons.ts +0 -132
- package/payload/platform/neo4j/migrations/007-conversation-archive-source.ts +0 -116
- package/payload/platform/neo4j/migrations/008-adminuser-accountid-backfill.ts +0 -85
- package/payload/platform/neo4j/migrations/009-conversation-archive-title.ts +0 -197
- package/payload/server/public/assets/data-DwZZ7qbH.js +0 -1
- package/payload/server/public/assets/graph-DceEv42K.js +0 -1
- /package/payload/server/public/assets/{jsx-runtime-DH5S-MwB.js → jsx-runtime-WW3O7tSz.js} +0 -0
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Graph — Maxy</title>
|
|
7
7
|
<link rel="icon" href="/favicon.ico">
|
|
8
|
-
<script type="module" crossorigin src="/assets/graph-
|
|
8
|
+
<script type="module" crossorigin src="/assets/graph-C-HOmfmU.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/chunk-DD-I1_y5.js">
|
|
10
|
-
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-
|
|
11
|
-
<link rel="modulepreload" crossorigin href="/assets/Checkbox-
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/useAdminFetch-
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/page-
|
|
14
|
-
<link rel="stylesheet" crossorigin href="/assets/jsx-runtime-
|
|
10
|
+
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-WW3O7tSz.js">
|
|
11
|
+
<link rel="modulepreload" crossorigin href="/assets/Checkbox-aCc0UGp3.js">
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/assets/useAdminFetch-BgDL3JGd.js">
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/page-DTmTvkNo.js">
|
|
14
|
+
<link rel="stylesheet" crossorigin href="/assets/jsx-runtime-BKoartnM.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
|
17
17
|
<div id="root"></div>
|
|
@@ -5,16 +5,16 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Real Agent</title>
|
|
7
7
|
<link rel="icon" href="/favicon.ico">
|
|
8
|
-
<script type="module" crossorigin src="/assets/admin-
|
|
8
|
+
<script type="module" crossorigin src="/assets/admin-CvwOOG4D.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/chunk-DD-I1_y5.js">
|
|
10
|
-
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-
|
|
10
|
+
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-WW3O7tSz.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/preload-helper-qlgyTAkD.js">
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/Checkbox-
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/useVoiceRecorder-
|
|
14
|
-
<link rel="modulepreload" crossorigin href="/assets/useAdminFetch-
|
|
15
|
-
<link rel="modulepreload" crossorigin href="/assets/page-
|
|
16
|
-
<link rel="modulepreload" crossorigin href="/assets/page-
|
|
17
|
-
<link rel="stylesheet" crossorigin href="/assets/jsx-runtime-
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/assets/Checkbox-aCc0UGp3.js">
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/useVoiceRecorder-Bx903Mk1.js">
|
|
14
|
+
<link rel="modulepreload" crossorigin href="/assets/useAdminFetch-BgDL3JGd.js">
|
|
15
|
+
<link rel="modulepreload" crossorigin href="/assets/page-D7LchjvY.js">
|
|
16
|
+
<link rel="modulepreload" crossorigin href="/assets/page-DTmTvkNo.js">
|
|
17
|
+
<link rel="stylesheet" crossorigin href="/assets/jsx-runtime-BKoartnM.css">
|
|
18
18
|
<link rel="stylesheet" crossorigin href="/assets/admin-CWMpccrR.css">
|
|
19
19
|
<link rel="stylesheet" href="/brand-defaults.css">
|
|
20
20
|
</head>
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Real Agent</title>
|
|
7
7
|
<link rel="icon" href="/favicon.ico">
|
|
8
|
-
<script type="module" crossorigin src="/assets/public-
|
|
8
|
+
<script type="module" crossorigin src="/assets/public-Br9YjNs_.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/chunk-DD-I1_y5.js">
|
|
10
|
-
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-
|
|
10
|
+
<link rel="modulepreload" crossorigin href="/assets/jsx-runtime-WW3O7tSz.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/preload-helper-qlgyTAkD.js">
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/Checkbox-
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/useVoiceRecorder-
|
|
14
|
-
<link rel="stylesheet" crossorigin href="/assets/jsx-runtime-
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/assets/Checkbox-aCc0UGp3.js">
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/useVoiceRecorder-Bx903Mk1.js">
|
|
14
|
+
<link rel="stylesheet" crossorigin href="/assets/jsx-runtime-BKoartnM.css">
|
|
15
15
|
<link rel="stylesheet" href="/brand-defaults.css">
|
|
16
16
|
</head>
|
|
17
17
|
<body>
|
package/payload/server/server.js
CHANGED
|
@@ -45,14 +45,23 @@ import {
|
|
|
45
45
|
vncLog,
|
|
46
46
|
waitForExit,
|
|
47
47
|
writeChromiumWrapper
|
|
48
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-S27QCBFQ.js";
|
|
49
49
|
import {
|
|
50
|
+
ACCOUNTS_DIR,
|
|
51
|
+
COMMERCIAL_MODE,
|
|
52
|
+
LOG_DIR,
|
|
53
|
+
MAXY_DIR,
|
|
54
|
+
PLATFORM_ROOT,
|
|
55
|
+
TELEGRAM_ADMIN_WEBHOOK_SECRET_FILE,
|
|
56
|
+
TELEGRAM_WEBHOOK_SECRET_FILE,
|
|
57
|
+
USERS_FILE,
|
|
50
58
|
agentLogStream,
|
|
51
59
|
clearSessionHistory,
|
|
52
60
|
completeGrantSetup,
|
|
53
61
|
getAccountIdForSession,
|
|
54
62
|
getAgentNameForSession,
|
|
55
63
|
getConversationIdForSession,
|
|
64
|
+
getDefaultAccountId,
|
|
56
65
|
getGrantForSession,
|
|
57
66
|
getGroupSlugForSession,
|
|
58
67
|
getRoleForSession,
|
|
@@ -60,6 +69,7 @@ import {
|
|
|
60
69
|
getUserIdForSession,
|
|
61
70
|
getUserNameForSession,
|
|
62
71
|
getVisitorIdForSession,
|
|
72
|
+
hasStubAccountDir,
|
|
63
73
|
interruptClient,
|
|
64
74
|
listAdminSessionsInProgress,
|
|
65
75
|
preConversationLogStream,
|
|
@@ -67,30 +77,18 @@ import {
|
|
|
67
77
|
registerGrantSession,
|
|
68
78
|
registerResumedSession,
|
|
69
79
|
registerSession,
|
|
80
|
+
resolveAccount,
|
|
81
|
+
resolveAgentConfig,
|
|
82
|
+
resolveDefaultAgentSlug,
|
|
83
|
+
resolveUserAccounts,
|
|
70
84
|
setAgentSessionId,
|
|
71
85
|
setConversationIdForSession,
|
|
72
86
|
setGroupContextForSession,
|
|
73
87
|
sigtermFlushStreamLogs,
|
|
74
88
|
unregisterSession,
|
|
89
|
+
validateAgentSlug,
|
|
75
90
|
validateSession
|
|
76
|
-
} from "./chunk-
|
|
77
|
-
import {
|
|
78
|
-
ACCOUNTS_DIR,
|
|
79
|
-
COMMERCIAL_MODE,
|
|
80
|
-
LOG_DIR,
|
|
81
|
-
MAXY_DIR,
|
|
82
|
-
PLATFORM_ROOT,
|
|
83
|
-
TELEGRAM_ADMIN_WEBHOOK_SECRET_FILE,
|
|
84
|
-
TELEGRAM_WEBHOOK_SECRET_FILE,
|
|
85
|
-
USERS_FILE,
|
|
86
|
-
getDefaultAccountId,
|
|
87
|
-
hasStubAccountDir,
|
|
88
|
-
resolveAccount,
|
|
89
|
-
resolveAgentConfig,
|
|
90
|
-
resolveDefaultAgentSlug,
|
|
91
|
-
resolveUserAccounts,
|
|
92
|
-
validateAgentSlug
|
|
93
|
-
} from "./chunk-OJZPS4BL.js";
|
|
91
|
+
} from "./chunk-2YG3AYAH.js";
|
|
94
92
|
import {
|
|
95
93
|
CLOUDFLARE_TASK_DIAGNOSTICS,
|
|
96
94
|
appendCloudflareSteps,
|
|
@@ -98,7 +96,7 @@ import {
|
|
|
98
96
|
openCloudflareTask,
|
|
99
97
|
readTunnelState,
|
|
100
98
|
resolveUnitGoneVerdict
|
|
101
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-DTWW35TK.js";
|
|
102
100
|
import {
|
|
103
101
|
GREETING_DIRECTIVE,
|
|
104
102
|
HAIKU_MODEL,
|
|
@@ -125,11 +123,10 @@ import {
|
|
|
125
123
|
projectAgent,
|
|
126
124
|
renameConversation,
|
|
127
125
|
runAdminUserSelfHeal,
|
|
128
|
-
runBootMigrations,
|
|
129
126
|
verifyAndGetConversationUpdatedAt,
|
|
130
127
|
verifyConversationOwnership,
|
|
131
128
|
writeAdminUserAndPerson
|
|
132
|
-
} from "./chunk-
|
|
129
|
+
} from "./chunk-CJWFM3WX.js";
|
|
133
130
|
import {
|
|
134
131
|
__commonJS,
|
|
135
132
|
__toESM
|
|
@@ -1871,17 +1868,17 @@ var INBOUND_TTL_MS = 20 * 6e4;
|
|
|
1871
1868
|
var INBOUND_MAX = 5e3;
|
|
1872
1869
|
var agentSentCache = /* @__PURE__ */ new Map();
|
|
1873
1870
|
var inboundCache = /* @__PURE__ */ new Map();
|
|
1874
|
-
function pruneCache(
|
|
1871
|
+
function pruneCache(cache2, ttl, max) {
|
|
1875
1872
|
const now = Date.now();
|
|
1876
|
-
for (const [key, entry] of
|
|
1877
|
-
if (now - entry.ts > ttl)
|
|
1873
|
+
for (const [key, entry] of cache2) {
|
|
1874
|
+
if (now - entry.ts > ttl) cache2.delete(key);
|
|
1878
1875
|
}
|
|
1879
|
-
if (
|
|
1880
|
-
const excess =
|
|
1876
|
+
if (cache2.size > max) {
|
|
1877
|
+
const excess = cache2.size - max;
|
|
1881
1878
|
let count = 0;
|
|
1882
|
-
for (const key of
|
|
1879
|
+
for (const key of cache2.keys()) {
|
|
1883
1880
|
if (count >= excess) break;
|
|
1884
|
-
|
|
1881
|
+
cache2.delete(key);
|
|
1885
1882
|
count++;
|
|
1886
1883
|
}
|
|
1887
1884
|
}
|
|
@@ -2250,35 +2247,22 @@ async function ensureWhatsAppConversation(input) {
|
|
|
2250
2247
|
}
|
|
2251
2248
|
}
|
|
2252
2249
|
|
|
2253
|
-
//
|
|
2250
|
+
// ../lib/account-enumeration/src/index.ts
|
|
2254
2251
|
import { readdirSync, readFileSync as readFileSync2 } from "fs";
|
|
2255
2252
|
import { resolve as resolve2 } from "path";
|
|
2256
2253
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
2257
|
-
var
|
|
2258
|
-
var cachedAccountsDir = null;
|
|
2259
|
-
function resolvePlatformAccountId(accountsDir = ACCOUNTS_DIR) {
|
|
2260
|
-
if (cached !== null && cachedAccountsDir === accountsDir) return cached;
|
|
2261
|
-
const valid = enumerateValidAccountIds(accountsDir);
|
|
2262
|
-
if (valid.length === 0) {
|
|
2263
|
-
throw new Error(
|
|
2264
|
-
`[whatsapp-persist] resolvePlatformAccountId: no platform account found under ${accountsDir} \u2014 corrupt install? Cannot stamp n.accountId without a valid UUID.`
|
|
2265
|
-
);
|
|
2266
|
-
}
|
|
2267
|
-
if (valid.length > 1) {
|
|
2268
|
-
throw new Error(
|
|
2269
|
-
`[whatsapp-persist] resolvePlatformAccountId: multiple platform accounts found under ${accountsDir} (${valid.join(", ")}) \u2014 Phase 0 invariant requires exactly one. Loud-fail rather than picking one silently.`
|
|
2270
|
-
);
|
|
2271
|
-
}
|
|
2272
|
-
cached = valid[0];
|
|
2273
|
-
cachedAccountsDir = accountsDir;
|
|
2274
|
-
return cached;
|
|
2275
|
-
}
|
|
2254
|
+
var cache = /* @__PURE__ */ new Map();
|
|
2276
2255
|
function enumerateValidAccountIds(accountsDir) {
|
|
2256
|
+
const cached2 = cache.get(accountsDir);
|
|
2257
|
+
if (cached2 !== void 0) return cached2;
|
|
2277
2258
|
let names;
|
|
2278
2259
|
try {
|
|
2279
2260
|
names = readdirSync(accountsDir);
|
|
2280
2261
|
} catch (err) {
|
|
2281
|
-
if (err.code === "ENOENT")
|
|
2262
|
+
if (err.code === "ENOENT") {
|
|
2263
|
+
cache.set(accountsDir, []);
|
|
2264
|
+
return [];
|
|
2265
|
+
}
|
|
2282
2266
|
throw err;
|
|
2283
2267
|
}
|
|
2284
2268
|
const valid = [];
|
|
@@ -2293,8 +2277,39 @@ function enumerateValidAccountIds(accountsDir) {
|
|
|
2293
2277
|
if (code === "ENOENT") continue;
|
|
2294
2278
|
}
|
|
2295
2279
|
}
|
|
2280
|
+
cache.set(accountsDir, valid);
|
|
2296
2281
|
return valid;
|
|
2297
2282
|
}
|
|
2283
|
+
function getAccountsDirFromEnv() {
|
|
2284
|
+
const root = process.env.MAXY_PLATFORM_ROOT;
|
|
2285
|
+
if (!root) {
|
|
2286
|
+
throw new Error(
|
|
2287
|
+
"[graph-write] MAXY_PLATFORM_ROOT not set \u2014 cannot enforce accountId gate. Set MAXY_PLATFORM_ROOT in the spawning process or pass `accountsDir` explicitly."
|
|
2288
|
+
);
|
|
2289
|
+
}
|
|
2290
|
+
return resolve2(root, "..", "data/accounts");
|
|
2291
|
+
}
|
|
2292
|
+
|
|
2293
|
+
// app/lib/whatsapp/platform-account-id.ts
|
|
2294
|
+
var cached = null;
|
|
2295
|
+
var cachedAccountsDir = null;
|
|
2296
|
+
function resolvePlatformAccountId(accountsDir = ACCOUNTS_DIR) {
|
|
2297
|
+
if (cached !== null && cachedAccountsDir === accountsDir) return cached;
|
|
2298
|
+
const valid = enumerateValidAccountIds(accountsDir);
|
|
2299
|
+
if (valid.length === 0) {
|
|
2300
|
+
throw new Error(
|
|
2301
|
+
`[whatsapp-persist] resolvePlatformAccountId: no platform account found under ${accountsDir} \u2014 corrupt install? Cannot stamp n.accountId without a valid UUID.`
|
|
2302
|
+
);
|
|
2303
|
+
}
|
|
2304
|
+
if (valid.length > 1) {
|
|
2305
|
+
throw new Error(
|
|
2306
|
+
`[whatsapp-persist] resolvePlatformAccountId: multiple platform accounts found under ${accountsDir} (${valid.join(", ")}) \u2014 Phase 0 invariant requires exactly one. Loud-fail rather than picking one silently.`
|
|
2307
|
+
);
|
|
2308
|
+
}
|
|
2309
|
+
cached = valid[0];
|
|
2310
|
+
cachedAccountsDir = accountsDir;
|
|
2311
|
+
return cached;
|
|
2312
|
+
}
|
|
2298
2313
|
|
|
2299
2314
|
// app/lib/whatsapp/inbound/media.ts
|
|
2300
2315
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
@@ -3922,7 +3937,7 @@ var SUPPORTED_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
|
3922
3937
|
"application/zip",
|
|
3923
3938
|
"application/x-zip-compressed"
|
|
3924
3939
|
]);
|
|
3925
|
-
var MAX_FILE_SIZE_BYTES =
|
|
3940
|
+
var MAX_FILE_SIZE_BYTES = 50 * 1024 * 1024;
|
|
3926
3941
|
var MAX_FILES_PER_MESSAGE = 5;
|
|
3927
3942
|
var MAX_ZIP_UNCOMPRESSED_BYTES = 100 * 1024 * 1024;
|
|
3928
3943
|
function assertSupportedMime(mimeType) {
|
|
@@ -3955,7 +3970,7 @@ async function storeAttachment(accountId, file) {
|
|
|
3955
3970
|
assertSupportedMime(file.type);
|
|
3956
3971
|
if (file.size > MAX_FILE_SIZE_BYTES) {
|
|
3957
3972
|
throw new Error(
|
|
3958
|
-
`File "${file.name}" exceeds the
|
|
3973
|
+
`File "${file.name}" exceeds the 50 MB limit (${(file.size / 1024 / 1024).toFixed(1)} MB).`
|
|
3959
3974
|
);
|
|
3960
3975
|
}
|
|
3961
3976
|
const buffer = Buffer.from(await file.arrayBuffer());
|
|
@@ -3965,7 +3980,7 @@ async function storePublicAttachment(sessionId, file, buffer) {
|
|
|
3965
3980
|
assertSupportedMime(file.type);
|
|
3966
3981
|
if (file.size > MAX_FILE_SIZE_BYTES) {
|
|
3967
3982
|
throw new Error(
|
|
3968
|
-
`File "${file.name}" exceeds the
|
|
3983
|
+
`File "${file.name}" exceeds the 50 MB limit (${(file.size / 1024 / 1024).toFixed(1)} MB).`
|
|
3969
3984
|
);
|
|
3970
3985
|
}
|
|
3971
3986
|
return writeAttachment(`public/${sessionId}`, file.name, file.type, file.size, buffer);
|
|
@@ -4009,7 +4024,7 @@ async function storeGeneratedFile(accountId, filePath) {
|
|
|
4009
4024
|
const fileStat = await stat2(filePath);
|
|
4010
4025
|
if (fileStat.size > MAX_FILE_SIZE_BYTES) {
|
|
4011
4026
|
throw new Error(
|
|
4012
|
-
`File exceeds the
|
|
4027
|
+
`File exceeds the 50 MB limit (${(fileStat.size / 1024 / 1024).toFixed(1)} MB).`
|
|
4013
4028
|
);
|
|
4014
4029
|
}
|
|
4015
4030
|
const filename = basename(filePath);
|
|
@@ -4386,7 +4401,7 @@ app3.post("/", async (c) => {
|
|
|
4386
4401
|
assertSupportedMime(file.type);
|
|
4387
4402
|
if (file.size > MAX_FILE_SIZE_BYTES) {
|
|
4388
4403
|
throw new Error(
|
|
4389
|
-
`File "${file.name}" exceeds the
|
|
4404
|
+
`File "${file.name}" exceeds the 50 MB limit (${(file.size / 1024 / 1024).toFixed(1)} MB).`
|
|
4390
4405
|
);
|
|
4391
4406
|
}
|
|
4392
4407
|
} catch (err) {
|
|
@@ -6192,7 +6207,7 @@ app7.post("/send-document", async (c) => {
|
|
|
6192
6207
|
}
|
|
6193
6208
|
const fileStat = await stat3(resolvedPath);
|
|
6194
6209
|
if (fileStat.size > MAX_FILE_SIZE_BYTES) {
|
|
6195
|
-
return c.json({ error: `File exceeds
|
|
6210
|
+
return c.json({ error: `File exceeds 50 MB limit (${(fileStat.size / 1024 / 1024).toFixed(1)} MB)` }, 400);
|
|
6196
6211
|
}
|
|
6197
6212
|
const buffer = Buffer.from(await readFile2(resolvedPath));
|
|
6198
6213
|
const filename = basename2(resolvedPath);
|
|
@@ -7496,7 +7511,7 @@ var app11 = new Hono();
|
|
|
7496
7511
|
app11.post("/cancel", requireAdminSession, async (c) => {
|
|
7497
7512
|
const session_key = c.var.sessionKey;
|
|
7498
7513
|
try {
|
|
7499
|
-
const { interruptClient: interruptClient2 } = await import("./client-pool-
|
|
7514
|
+
const { interruptClient: interruptClient2 } = await import("./client-pool-SMWCZMZG.js");
|
|
7500
7515
|
await interruptClient2(session_key);
|
|
7501
7516
|
return c.json({ ok: true });
|
|
7502
7517
|
} catch (err) {
|
|
@@ -7544,7 +7559,7 @@ app11.post("/", requireAdminSession, async (c) => {
|
|
|
7544
7559
|
assertSupportedMime(file.type);
|
|
7545
7560
|
if (file.size > MAX_FILE_SIZE_BYTES) {
|
|
7546
7561
|
throw new Error(
|
|
7547
|
-
`File "${file.name}" exceeds the
|
|
7562
|
+
`File "${file.name}" exceeds the 50 MB limit (${(file.size / 1024 / 1024).toFixed(1)} MB).`
|
|
7548
7563
|
);
|
|
7549
7564
|
}
|
|
7550
7565
|
} catch (err) {
|
|
@@ -9965,7 +9980,7 @@ app22.post("/upload", requireAdminSession, async (c) => {
|
|
|
9965
9980
|
if (file.size > MAX_FILE_SIZE_BYTES) {
|
|
9966
9981
|
console.error(`[data] file-upload rejected reason="size" filename="${file.name}" size=${file.size}`);
|
|
9967
9982
|
return c.json({
|
|
9968
|
-
error: `File "${file.name}" exceeds the
|
|
9983
|
+
error: `File "${file.name}" exceeds the 50 MB limit (${(file.size / 1024 / 1024).toFixed(1)} MB).`
|
|
9969
9984
|
}, 422);
|
|
9970
9985
|
}
|
|
9971
9986
|
if (!SUPPORTED_MIME_TYPES.has(file.type)) {
|
|
@@ -13050,13 +13065,6 @@ try {
|
|
|
13050
13065
|
console.error(`[session] backfill startup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
13051
13066
|
}
|
|
13052
13067
|
})();
|
|
13053
|
-
(async () => {
|
|
13054
|
-
try {
|
|
13055
|
-
await runBootMigrations();
|
|
13056
|
-
} catch (err) {
|
|
13057
|
-
console.error(`[migration] runBootMigrations rejected: ${err instanceof Error ? err.message : String(err)}`);
|
|
13058
|
-
}
|
|
13059
|
-
})();
|
|
13060
13068
|
(async () => {
|
|
13061
13069
|
try {
|
|
13062
13070
|
if (!existsSync23(USERS_FILE)) return;
|
|
@@ -13076,6 +13084,12 @@ try {
|
|
|
13076
13084
|
}
|
|
13077
13085
|
})();
|
|
13078
13086
|
startGraphHealthTimer();
|
|
13087
|
+
try {
|
|
13088
|
+
const accounts = enumerateValidAccountIds(getAccountsDirFromEnv());
|
|
13089
|
+
console.error(`[graph-health] account-enumeration accounts=${accounts.length}`);
|
|
13090
|
+
} catch (err) {
|
|
13091
|
+
console.error(`[graph-health] account-enumeration unavailable reason=${err instanceof Error ? err.message : String(err)}`);
|
|
13092
|
+
}
|
|
13079
13093
|
var configDirForWhatsApp = basename5(MAXY_DIR) || ".maxy";
|
|
13080
13094
|
var bootAccount = resolveAccount();
|
|
13081
13095
|
var bootAccountConfig = bootAccount?.config;
|
|
@@ -13093,7 +13107,7 @@ autoDeliverPremiumPlugins(bootEntitlement?.purchasedPlugins ?? void 0);
|
|
|
13093
13107
|
(async () => {
|
|
13094
13108
|
if (!bootAccount) return;
|
|
13095
13109
|
try {
|
|
13096
|
-
const { recoverRunningCloudflareTasks } = await import("./cloudflare-task-tracker-
|
|
13110
|
+
const { recoverRunningCloudflareTasks } = await import("./cloudflare-task-tracker-NQK7A2EQ.js");
|
|
13097
13111
|
const result = await recoverRunningCloudflareTasks(
|
|
13098
13112
|
bootAccount.accountId,
|
|
13099
13113
|
configDirForWhatsApp,
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Migration 001: Backfill scope property on all existing nodes
|
|
3
|
-
//
|
|
4
|
-
// Sets scope on every node that participates in memory-search.
|
|
5
|
-
// Product knowledge → 'public', internal data → 'admin'.
|
|
6
|
-
// Safe to re-run: only touches nodes where scope IS NULL.
|
|
7
|
-
//
|
|
8
|
-
// Run via: cypher-shell -u neo4j -p <password> -f 001-backfill-scope.cypher
|
|
9
|
-
// ============================================================
|
|
10
|
-
|
|
11
|
-
// --- Product knowledge (public agent can see) ---
|
|
12
|
-
|
|
13
|
-
MATCH (n:Question) WHERE n.scope IS NULL SET n.scope = 'public';
|
|
14
|
-
MATCH (n:DefinedTerm) WHERE n.scope IS NULL SET n.scope = 'public';
|
|
15
|
-
MATCH (n:Service) WHERE n.scope IS NULL SET n.scope = 'public';
|
|
16
|
-
MATCH (n:Review) WHERE n.scope IS NULL SET n.scope = 'public';
|
|
17
|
-
MATCH (n:PriceSpecification) WHERE n.scope IS NULL SET n.scope = 'public';
|
|
18
|
-
MATCH (n:LocalBusiness) WHERE n.scope IS NULL SET n.scope = 'public';
|
|
19
|
-
MATCH (n:KnowledgeDocument) WHERE n.scope IS NULL SET n.scope = 'public';
|
|
20
|
-
MATCH (n:Section) WHERE n.scope IS NULL SET n.scope = 'public';
|
|
21
|
-
MATCH (n:Chunk) WHERE n.scope IS NULL SET n.scope = 'public';
|
|
22
|
-
MATCH (n:DigitalDocument) WHERE n.scope IS NULL SET n.scope = 'public';
|
|
23
|
-
|
|
24
|
-
// --- Internal data (admin agent only) ---
|
|
25
|
-
|
|
26
|
-
MATCH (n:CreativeWork) WHERE n.scope IS NULL SET n.scope = 'admin';
|
|
27
|
-
MATCH (n:Task) WHERE n.scope IS NULL SET n.scope = 'admin';
|
|
28
|
-
MATCH (n:Person) WHERE n.scope IS NULL SET n.scope = 'admin';
|
|
29
|
-
MATCH (n:Event) WHERE n.scope IS NULL SET n.scope = 'admin';
|
|
30
|
-
MATCH (n:OnboardingState) WHERE n.scope IS NULL SET n.scope = 'admin';
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Migration 002 — Project file-based public agents into the graph (Task 837).
|
|
3
|
-
*
|
|
4
|
-
* Two passes:
|
|
5
|
-
*
|
|
6
|
-
* 1. Walk every account directory under data/accounts/<accountId>/agents/
|
|
7
|
-
* and call projectAgent(accountId, accountDir, slug) for each non-admin
|
|
8
|
-
* agent that has a config.json. The projector is idempotent: re-running
|
|
9
|
-
* this migration produces no duplicate nodes or edges.
|
|
10
|
-
*
|
|
11
|
-
* 2. For every existing public Conversation that carries an agentSlug
|
|
12
|
-
* property, MATCH the corresponding :Agent and MERGE the
|
|
13
|
-
* (:Conversation)-[:HANDLED_BY]->(:Agent) edge. Conversations whose
|
|
14
|
-
* slug doesn't resolve to an Agent (orphan slugs from deleted agents,
|
|
15
|
-
* or DM-channel public flows that haven't been extended to register a
|
|
16
|
-
* slug) are left edge-less; they will gain the edge automatically once
|
|
17
|
-
* the slug is registered or a new agent at that slug is projected.
|
|
18
|
-
*
|
|
19
|
-
* Run via the platform/ui standalone runtime so it picks up the same
|
|
20
|
-
* NEO4J_URI / accounts-directory resolution as the server:
|
|
21
|
-
*
|
|
22
|
-
* cd platform/ui && \
|
|
23
|
-
* NEO4J_URI=bolt://… NEO4J_PASSWORD=… \
|
|
24
|
-
* npx tsx ../neo4j/migrations/002-project-public-agents.ts
|
|
25
|
-
*
|
|
26
|
-
* Output: structured `[agent-graph-backfill]` lines per account + a final
|
|
27
|
-
* totals line. A non-zero exit code on any per-account failure surfaces to
|
|
28
|
-
* the operator; subsequent accounts are still attempted (the migration is
|
|
29
|
-
* isolating by account, not all-or-nothing).
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
import { existsSync, readdirSync } from "node:fs";
|
|
33
|
-
import { resolve } from "node:path";
|
|
34
|
-
import {
|
|
35
|
-
projectAgent,
|
|
36
|
-
getSession,
|
|
37
|
-
} from "../../ui/app/lib/neo4j-store";
|
|
38
|
-
import { ACCOUNTS_DIR } from "../../ui/app/lib/claude-agent/account";
|
|
39
|
-
|
|
40
|
-
interface PerAccountStats {
|
|
41
|
-
accountId: string;
|
|
42
|
-
agents: number;
|
|
43
|
-
agentFailures: number;
|
|
44
|
-
convEdges: number;
|
|
45
|
-
convOrphans: number;
|
|
46
|
-
convCandidates: number;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async function projectAccountAgents(
|
|
50
|
-
accountId: string,
|
|
51
|
-
accountDir: string,
|
|
52
|
-
): Promise<{ agents: number; agentFailures: number }> {
|
|
53
|
-
const agentsDir = resolve(accountDir, "agents");
|
|
54
|
-
if (!existsSync(agentsDir)) return { agents: 0, agentFailures: 0 };
|
|
55
|
-
|
|
56
|
-
let agents = 0;
|
|
57
|
-
let agentFailures = 0;
|
|
58
|
-
for (const entry of readdirSync(agentsDir, { withFileTypes: true })) {
|
|
59
|
-
if (!entry.isDirectory()) continue;
|
|
60
|
-
if (entry.name === "admin") continue;
|
|
61
|
-
|
|
62
|
-
const configPath = resolve(agentsDir, entry.name, "config.json");
|
|
63
|
-
if (!existsSync(configPath)) continue;
|
|
64
|
-
|
|
65
|
-
try {
|
|
66
|
-
await projectAgent(accountId, accountDir, entry.name);
|
|
67
|
-
agents++;
|
|
68
|
-
} catch (err) {
|
|
69
|
-
agentFailures++;
|
|
70
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
71
|
-
console.error(
|
|
72
|
-
`[agent-graph-backfill] account=${accountId.slice(0, 8)} agent=${entry.name} project FAILED error="${msg}"`,
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return { agents, agentFailures };
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
interface HandledByBackfillStats {
|
|
80
|
-
candidates: number;
|
|
81
|
-
edges: number;
|
|
82
|
-
orphans: number;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Two-pass: count candidate Conversations (those carrying agentSlug),
|
|
87
|
-
* then OPTIONAL MATCH to surface orphans separately from successful merges.
|
|
88
|
-
* A hard MATCH-then-MATCH chain would silently filter orphan-slug rows out,
|
|
89
|
-
* making `edges=0` indistinguishable from "no public conversations exist"
|
|
90
|
-
* vs "every slug is orphaned" — different incidents, different fixes.
|
|
91
|
-
*/
|
|
92
|
-
async function backfillHandledByEdges(accountId: string): Promise<HandledByBackfillStats> {
|
|
93
|
-
const session = getSession();
|
|
94
|
-
try {
|
|
95
|
-
const result = await session.run(
|
|
96
|
-
`MATCH (c:Conversation {accountId: $accountId, agentType: 'public'})
|
|
97
|
-
WHERE c.agentSlug IS NOT NULL
|
|
98
|
-
OPTIONAL MATCH (a:Agent {accountId: $accountId, slug: c.agentSlug})
|
|
99
|
-
FOREACH (_ IN CASE WHEN a IS NULL THEN [] ELSE [1] END | MERGE (c)-[:HANDLED_BY]->(a))
|
|
100
|
-
RETURN
|
|
101
|
-
count(c) AS candidates,
|
|
102
|
-
sum(CASE WHEN a IS NULL THEN 0 ELSE 1 END) AS edges,
|
|
103
|
-
sum(CASE WHEN a IS NULL THEN 1 ELSE 0 END) AS orphans`,
|
|
104
|
-
{ accountId },
|
|
105
|
-
);
|
|
106
|
-
const toNum = (v: unknown): number => {
|
|
107
|
-
if (typeof v === "number") return v;
|
|
108
|
-
if (v && typeof (v as { toNumber: () => number }).toNumber === "function") {
|
|
109
|
-
return (v as { toNumber: () => number }).toNumber();
|
|
110
|
-
}
|
|
111
|
-
return 0;
|
|
112
|
-
};
|
|
113
|
-
return {
|
|
114
|
-
candidates: toNum(result.records[0]?.get("candidates")),
|
|
115
|
-
edges: toNum(result.records[0]?.get("edges")),
|
|
116
|
-
orphans: toNum(result.records[0]?.get("orphans")),
|
|
117
|
-
};
|
|
118
|
-
} finally {
|
|
119
|
-
await session.close();
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
async function main(): Promise<void> {
|
|
124
|
-
const start = Date.now();
|
|
125
|
-
|
|
126
|
-
if (!existsSync(ACCOUNTS_DIR)) {
|
|
127
|
-
console.error(`[agent-graph-backfill] ACCOUNTS_DIR missing at ${ACCOUNTS_DIR} — nothing to do`);
|
|
128
|
-
process.exit(0);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const accountEntries = readdirSync(ACCOUNTS_DIR, { withFileTypes: true })
|
|
132
|
-
.filter((e) => e.isDirectory());
|
|
133
|
-
|
|
134
|
-
console.error(`[agent-graph-backfill] start accounts=${accountEntries.length}`);
|
|
135
|
-
|
|
136
|
-
let totalAgents = 0;
|
|
137
|
-
let totalAgentFailures = 0;
|
|
138
|
-
let totalConvEdges = 0;
|
|
139
|
-
let totalConvOrphans = 0;
|
|
140
|
-
let totalConvCandidates = 0;
|
|
141
|
-
const perAccount: PerAccountStats[] = [];
|
|
142
|
-
|
|
143
|
-
for (const entry of accountEntries) {
|
|
144
|
-
const accountDir = resolve(ACCOUNTS_DIR, entry.name);
|
|
145
|
-
const accountId = entry.name;
|
|
146
|
-
const accountStart = Date.now();
|
|
147
|
-
|
|
148
|
-
const { agents, agentFailures } = await projectAccountAgents(accountId, accountDir);
|
|
149
|
-
totalAgents += agents;
|
|
150
|
-
totalAgentFailures += agentFailures;
|
|
151
|
-
|
|
152
|
-
let convStats: HandledByBackfillStats = { candidates: 0, edges: 0, orphans: 0 };
|
|
153
|
-
try {
|
|
154
|
-
convStats = await backfillHandledByEdges(accountId);
|
|
155
|
-
totalConvEdges += convStats.edges;
|
|
156
|
-
totalConvOrphans += convStats.orphans;
|
|
157
|
-
totalConvCandidates += convStats.candidates;
|
|
158
|
-
} catch (err) {
|
|
159
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
160
|
-
console.error(
|
|
161
|
-
`[agent-graph-backfill] account=${accountId.slice(0, 8)} handled-by-backfill FAILED error="${msg}"`,
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
perAccount.push({
|
|
166
|
-
accountId,
|
|
167
|
-
agents,
|
|
168
|
-
agentFailures,
|
|
169
|
-
convEdges: convStats.edges,
|
|
170
|
-
convOrphans: convStats.orphans,
|
|
171
|
-
convCandidates: convStats.candidates,
|
|
172
|
-
});
|
|
173
|
-
const ms = Date.now() - accountStart;
|
|
174
|
-
console.error(
|
|
175
|
-
`[agent-graph-backfill] account=${accountId.slice(0, 8)} agents=${agents} failures=${agentFailures} conv-candidates=${convStats.candidates} conv-edges=${convStats.edges} conv-orphans=${convStats.orphans} ms=${ms}`,
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
const ms = Date.now() - start;
|
|
180
|
-
console.error(
|
|
181
|
-
`[agent-graph-backfill] done totals: agents=${totalAgents} agent-failures=${totalAgentFailures} conv-candidates=${totalConvCandidates} conv-edges=${totalConvEdges} conv-orphans=${totalConvOrphans} ms=${ms}`,
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
process.exit(totalAgentFailures > 0 ? 1 : 0);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
main().catch((err) => {
|
|
188
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
189
|
-
console.error(`[agent-graph-backfill] fatal error="${msg}"`);
|
|
190
|
-
process.exit(2);
|
|
191
|
-
});
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// Migration 003 — Person.name eradication (Task 849)
|
|
3
|
-
//
|
|
4
|
-
// Removes the denormalised `name` property from every Person node.
|
|
5
|
-
// `Person.name` is forbidden by schema-base.md "Forbidden Properties":
|
|
6
|
-
// the canonical fields are `givenName` + `familyName`, composed at
|
|
7
|
-
// read time by display-helpers.ts. Persisted `name` was a divergence
|
|
8
|
-
// trap — LLM extraction emitted `name = givenName` ("Dan") alongside
|
|
9
|
-
// the structured pair, so the canvas rendered "Dan" instead of
|
|
10
|
-
// "Dan Brett".
|
|
11
|
-
//
|
|
12
|
-
// Idempotent: subsequent runs find no Persons with `name` set and
|
|
13
|
-
// return removed=0.
|
|
14
|
-
//
|
|
15
|
-
// Applied at boot by platform/ui/app/lib/neo4j-migrations.ts. Safe to
|
|
16
|
-
// run manually:
|
|
17
|
-
// cypher-shell -u neo4j -p <password> -a $NEO4J_URI \
|
|
18
|
-
// -f platform/neo4j/migrations/003-person-name-eradicate.cypher
|
|
19
|
-
// ============================================================
|
|
20
|
-
|
|
21
|
-
MATCH (p:Person)
|
|
22
|
-
WHERE p.name IS NOT NULL
|
|
23
|
-
REMOVE p.name
|
|
24
|
-
RETURN count(p) AS removed
|