@rubytech/create-maxy-code 0.1.417 → 0.1.419
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/dist/__tests__/brand-port-uniqueness.test.js +74 -0
- package/dist/known-brands.js +1 -0
- package/package.json +1 -1
- package/payload/platform/config/brand-registry.json +8 -0
- package/payload/platform/lib/active-rules/dist/index.d.ts +35 -0
- package/payload/platform/lib/active-rules/dist/index.d.ts.map +1 -0
- package/payload/platform/lib/active-rules/dist/index.js +94 -0
- package/payload/platform/lib/active-rules/dist/index.js.map +1 -0
- package/payload/platform/lib/active-rules/package.json +7 -0
- package/payload/platform/lib/active-rules/src/index.test.ts +89 -0
- package/payload/platform/lib/active-rules/src/index.ts +133 -0
- package/payload/platform/lib/active-rules/tsconfig.json +9 -0
- package/payload/platform/package.json +4 -3
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +14 -2
- package/payload/platform/plugins/docs/references/internals.md +10 -0
- package/payload/platform/plugins/docs/references/memory-guide.md +2 -0
- package/payload/platform/plugins/docs/references/outlook-guide.md +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-read-active-rules.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-read-active-rules.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-read-active-rules.test.js +49 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-read-active-rules.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-reconcile.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-reconcile.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-reconcile.test.js +99 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/profile-update-reconcile.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.d.ts +3 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js +11 -3
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts +21 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +106 -14
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/calendar-write.test.js +24 -0
- package/payload/platform/plugins/outlook/mcp/dist/__tests__/calendar-write.test.js.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.d.ts +15 -2
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.d.ts.map +1 -1
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.js +16 -7
- package/payload/platform/plugins/outlook/mcp/dist/tools/calendar-create.js.map +1 -1
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js +10 -5
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +9 -1
- package/payload/platform/scripts/__tests__/provision-role-stamp.test.sh +3 -0
- package/payload/platform/scripts/lib/provision-account-dir.sh +9 -1
- package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.d.ts +1 -1
- package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.js +5 -1
- package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts +1 -0
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +29 -2
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +14 -0
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/preference-reconciliation-audit.d.ts +46 -0
- package/payload/platform/services/claude-session-manager/dist/preference-reconciliation-audit.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/preference-reconciliation-audit.js +96 -0
- package/payload/platform/services/claude-session-manager/dist/preference-reconciliation-audit.js.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +33 -0
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +54 -5
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.js +5 -1
- package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts +6 -0
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js +20 -0
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
- package/payload/platform/services/telegram-channel/dist/instructions.d.ts +9 -0
- package/payload/platform/services/telegram-channel/dist/instructions.d.ts.map +1 -0
- package/payload/platform/services/telegram-channel/dist/instructions.js +100 -0
- package/payload/platform/services/telegram-channel/dist/instructions.js.map +1 -0
- package/payload/platform/services/telegram-channel/dist/notification.d.ts +93 -0
- package/payload/platform/services/telegram-channel/dist/notification.d.ts.map +1 -0
- package/payload/platform/services/telegram-channel/dist/notification.js +119 -0
- package/payload/platform/services/telegram-channel/dist/notification.js.map +1 -0
- package/payload/platform/services/telegram-channel/dist/server.d.ts +40 -0
- package/payload/platform/services/telegram-channel/dist/server.d.ts.map +1 -0
- package/payload/platform/services/telegram-channel/dist/server.js +291 -0
- package/payload/platform/services/telegram-channel/dist/server.js.map +1 -0
- package/payload/platform/services/telegram-channel/dist/turn-follow.d.ts +28 -0
- package/payload/platform/services/telegram-channel/dist/turn-follow.d.ts.map +1 -0
- package/payload/platform/services/telegram-channel/dist/turn-follow.js +188 -0
- package/payload/platform/services/telegram-channel/dist/turn-follow.js.map +1 -0
- package/payload/platform/services/webchat-channel/dist/notification.d.ts +5 -0
- package/payload/platform/services/webchat-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/webchat-channel/dist/notification.js +6 -1
- package/payload/platform/services/webchat-channel/dist/notification.js.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts +6 -0
- package/payload/platform/services/whatsapp-channel/dist/notification.d.ts.map +1 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.js +8 -1
- package/payload/platform/services/whatsapp-channel/dist/notification.js.map +1 -1
- package/payload/platform/templates/agents/passive/IDENTITY.md +21 -0
- package/payload/server/public/assets/{AdminLoginScreens-CBTx7ZPK.js → AdminLoginScreens-B1PkOF66.js} +1 -1
- package/payload/server/public/assets/AdminShell-D8wNArGQ.js +2 -0
- package/payload/server/public/assets/{Checkbox-BHTxekRB.js → Checkbox-Bm9Er726.js} +1 -1
- package/payload/server/public/assets/{Transcript-5kLbBInN.js → Transcript-CBIyQ8T5.js} +1 -1
- package/payload/server/public/assets/{admin-BWCLE32N.js → admin-CWM9G_yA.js} +1 -1
- package/payload/server/public/assets/{browser-CRvCPsvV.js → browser-D8QhNffV.js} +1 -1
- package/payload/server/public/assets/{calendar-BI-kd-QP.js → calendar-qob5K4t_.js} +1 -1
- package/payload/server/public/assets/chat-BNrxVUF6.js +1 -0
- package/payload/server/public/assets/chevron-left-BQThFVrd.js +1 -0
- package/payload/server/public/assets/data-C-EqNbRi.js +1 -0
- package/payload/server/public/assets/{graph-BFSyW_5i.js → graph-DZ2HMpIB.js} +1 -1
- package/payload/server/public/assets/{graph-labels-DEjD_qJh.js → graph-labels-BFG4bjXQ.js} +1 -1
- package/payload/server/public/assets/{maximize-2-BcMJNeCB.js → maximize-2-DkZ40lSl.js} +1 -1
- package/payload/server/public/assets/{operator-Dtvm9ero.js → operator-FrXrSsBj.js} +1 -1
- package/payload/server/public/assets/page-CHWMI9Tm.js +32 -0
- package/payload/server/public/assets/{page-TXi9dmaB.js → page-CXKV01gT.js} +1 -1
- package/payload/server/public/assets/{public-DBx3U0r8.js → public-2p1pJ4WF.js} +1 -1
- package/payload/server/public/assets/{rotate-ccw-8ti3QkeY.js → rotate-ccw-D3o_bMBA.js} +1 -1
- package/payload/server/public/assets/useSubAccountSwitcher-8dLvF3Ux.js +9 -0
- package/payload/server/public/browser.html +3 -3
- package/payload/server/public/calendar.html +4 -4
- package/payload/server/public/chat.html +8 -8
- package/payload/server/public/data.html +7 -7
- package/payload/server/public/graph.html +8 -8
- package/payload/server/public/index.html +10 -10
- package/payload/server/public/operator.html +10 -10
- package/payload/server/public/public.html +8 -8
- package/payload/server/server.js +237 -38
- package/payload/server/public/assets/AdminShell-DPHUeXea.js +0 -2
- package/payload/server/public/assets/chat-DFy8hb1y.js +0 -1
- package/payload/server/public/assets/chevron-left-Bggm5B5U.js +0 -1
- package/payload/server/public/assets/data-HvZ69Ya1.js +0 -1
- package/payload/server/public/assets/page-C_pm3hl3.js +0 -32
- package/payload/server/public/assets/useSubAccountSwitcher-Bc5dOBdI.js +0 -9
package/payload/server/server.js
CHANGED
|
@@ -116,8 +116,84 @@ import {
|
|
|
116
116
|
__toESM
|
|
117
117
|
} from "./chunk-PFF6I7KP.js";
|
|
118
118
|
|
|
119
|
-
// ../lib/
|
|
119
|
+
// ../lib/active-rules/dist/index.js
|
|
120
120
|
var require_dist = __commonJS({
|
|
121
|
+
"../lib/active-rules/dist/index.js"(exports) {
|
|
122
|
+
"use strict";
|
|
123
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
124
|
+
exports.ACTIVE_CANDIDATE_LIMIT = exports.ACTIVE_CANDIDATE_FLOOR = exports.INJECTION_RULE_CAP = exports.SAME_SUBJECT_COSINE = void 0;
|
|
125
|
+
exports.cosine = cosine;
|
|
126
|
+
exports.deconflictBySubject = deconflictBySubject;
|
|
127
|
+
exports.formatStandingRulesBlock = formatStandingRulesBlock2;
|
|
128
|
+
exports.queryActiveRuleCandidates = queryActiveRuleCandidates;
|
|
129
|
+
exports.activeRuleSet = activeRuleSet2;
|
|
130
|
+
exports.SAME_SUBJECT_COSINE = 0.85;
|
|
131
|
+
exports.INJECTION_RULE_CAP = 12;
|
|
132
|
+
exports.ACTIVE_CANDIDATE_FLOOR = 0.4;
|
|
133
|
+
exports.ACTIVE_CANDIDATE_LIMIT = 30;
|
|
134
|
+
function cosine(a, b) {
|
|
135
|
+
if (!a.length || !b.length || a.length !== b.length)
|
|
136
|
+
return 0;
|
|
137
|
+
let dot = 0;
|
|
138
|
+
let na = 0;
|
|
139
|
+
let nb = 0;
|
|
140
|
+
for (let i = 0; i < a.length; i++) {
|
|
141
|
+
dot += a[i] * b[i];
|
|
142
|
+
na += a[i] * a[i];
|
|
143
|
+
nb += b[i] * b[i];
|
|
144
|
+
}
|
|
145
|
+
if (na === 0 || nb === 0)
|
|
146
|
+
return 0;
|
|
147
|
+
return dot / (Math.sqrt(na) * Math.sqrt(nb));
|
|
148
|
+
}
|
|
149
|
+
function deconflictBySubject(records, cosineThreshold = exports.SAME_SUBJECT_COSINE) {
|
|
150
|
+
const winners = [];
|
|
151
|
+
for (const r of records) {
|
|
152
|
+
const emb = r.embedding;
|
|
153
|
+
const isDup = Array.isArray(emb) && emb.length > 0 && winners.some((w) => Array.isArray(w.embedding) && w.embedding.length > 0 && cosine(emb, w.embedding) >= cosineThreshold);
|
|
154
|
+
if (!isDup)
|
|
155
|
+
winners.push(r);
|
|
156
|
+
}
|
|
157
|
+
return winners.map(({ embedding: _embedding, ...rest }) => rest);
|
|
158
|
+
}
|
|
159
|
+
function formatStandingRulesBlock2(rules, cap = exports.INJECTION_RULE_CAP) {
|
|
160
|
+
if (rules.length === 0)
|
|
161
|
+
return "";
|
|
162
|
+
const lines = rules.slice(0, cap).map((r) => `- ${r.value}`);
|
|
163
|
+
return `## Standing rules
|
|
164
|
+
${lines.join("\n")}`;
|
|
165
|
+
}
|
|
166
|
+
async function queryActiveRuleCandidates(session, accountId) {
|
|
167
|
+
const result = await session.run(`
|
|
168
|
+
MATCH (pref:Preference {accountId: $accountId, scope: 'admin'})
|
|
169
|
+
WHERE NOT pref:Trashed AND pref.deletedAt IS NULL
|
|
170
|
+
AND coalesce(pref.notApplicable, false) = false
|
|
171
|
+
AND pref.confidence >= $floor
|
|
172
|
+
RETURN pref.preferenceId AS preferenceId, pref.category AS category,
|
|
173
|
+
pref.key AS key, pref.value AS value, pref.confidence AS confidence,
|
|
174
|
+
pref.observedAt AS observedAt, pref.embedding AS embedding
|
|
175
|
+
ORDER BY pref.confidence DESC, pref.observedAt DESC
|
|
176
|
+
LIMIT ${exports.ACTIVE_CANDIDATE_LIMIT}
|
|
177
|
+
`, { accountId, floor: exports.ACTIVE_CANDIDATE_FLOOR });
|
|
178
|
+
return result.records.map((r) => ({
|
|
179
|
+
preferenceId: r.get("preferenceId"),
|
|
180
|
+
category: r.get("category"),
|
|
181
|
+
key: r.get("key"),
|
|
182
|
+
value: r.get("value"),
|
|
183
|
+
confidence: r.get("confidence"),
|
|
184
|
+
observedAt: r.get("observedAt") ?? "",
|
|
185
|
+
embedding: r.get("embedding") ?? null
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
async function activeRuleSet2(session, accountId, cap = exports.INJECTION_RULE_CAP) {
|
|
189
|
+
const candidates = await queryActiveRuleCandidates(session, accountId);
|
|
190
|
+
return deconflictBySubject(candidates).slice(0, cap);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// ../lib/graph-trash/dist/index.js
|
|
196
|
+
var require_dist2 = __commonJS({
|
|
121
197
|
"../lib/graph-trash/dist/index.js"(exports) {
|
|
122
198
|
"use strict";
|
|
123
199
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -398,7 +474,7 @@ var require_dist = __commonJS({
|
|
|
398
474
|
});
|
|
399
475
|
|
|
400
476
|
// ../lib/graph-style/dist/index.js
|
|
401
|
-
var
|
|
477
|
+
var require_dist3 = __commonJS({
|
|
402
478
|
"../lib/graph-style/dist/index.js"(exports) {
|
|
403
479
|
"use strict";
|
|
404
480
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -781,7 +857,7 @@ var require_conversation_provenance = __commonJS({
|
|
|
781
857
|
"use strict";
|
|
782
858
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
783
859
|
exports.injectConversationProvenance = injectConversationProvenance;
|
|
784
|
-
var index_js_1 =
|
|
860
|
+
var index_js_1 = require_dist4();
|
|
785
861
|
async function injectConversationProvenance(params) {
|
|
786
862
|
const { session, relationships, accountId, writeLabels, conversationNodeId, logNamespace, tool } = params;
|
|
787
863
|
const original = [...relationships];
|
|
@@ -831,7 +907,7 @@ var require_conversation_provenance = __commonJS({
|
|
|
831
907
|
});
|
|
832
908
|
|
|
833
909
|
// ../lib/graph-write/dist/index.js
|
|
834
|
-
var
|
|
910
|
+
var require_dist4 = __commonJS({
|
|
835
911
|
"../lib/graph-write/dist/index.js"(exports) {
|
|
836
912
|
"use strict";
|
|
837
913
|
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -1308,6 +1384,7 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
1308
1384
|
// server/index.ts
|
|
1309
1385
|
import { readFileSync as readFileSync35, existsSync as existsSync33, watchFile } from "fs";
|
|
1310
1386
|
import { spawn as spawn3 } from "child_process";
|
|
1387
|
+
import { createHash as createHash6 } from "crypto";
|
|
1311
1388
|
import { resolve as resolve33, join as join35, basename as basename13 } from "path";
|
|
1312
1389
|
import { homedir as homedir3 } from "os";
|
|
1313
1390
|
import { monitorEventLoopDelay } from "perf_hooks";
|
|
@@ -1739,7 +1816,13 @@ var WhatsAppConfigSchema = z.object({
|
|
|
1739
1816
|
accounts: z.record(z.string(), WhatsAppAccountSchema.optional()).optional().describe("Per-account config keyed by account ID."),
|
|
1740
1817
|
dmPolicy: DmPolicySchema.optional().default("disabled").describe("Who can message your public agent via WhatsApp DM. 'Open' lets anyone message. 'Allowlist' restricts to approved phone numbers. 'Disabled' blocks all public messages."),
|
|
1741
1818
|
adminPhones: z.array(z.string()).optional().describe("Phone numbers (E.164) that route to the admin agent. Managed via add-admin-phone / remove-admin-phone. Authoritative only on the account that owns the WhatsApp paired socket; a list on any other account is inert and purged at boot \u2014 use accountManagers for sub-account routing."),
|
|
1742
|
-
accountManagers: z.record(
|
|
1819
|
+
accountManagers: z.record(
|
|
1820
|
+
z.string(),
|
|
1821
|
+
z.union([
|
|
1822
|
+
z.string(),
|
|
1823
|
+
z.object({ managesAccount: z.string(), mode: z.enum(["active", "passive"]).optional() })
|
|
1824
|
+
])
|
|
1825
|
+
).optional().describe("Account-manager bindings: E.164 phone \u2192 sub-account. The value is a bare sub-account UUID (mode 'active', the default: a full admin session) or { managesAccount, mode } where mode 'passive' selects a constrained requirement-intake spawn (only work-create, no reply). A bare string and an object without mode both resolve to 'active'. Managed via add-account-manager / remove-account-manager. A phone here must not also be in adminPhones."),
|
|
1743
1826
|
allowFrom: z.array(z.string()).optional().describe("Phone numbers allowed to message the public agent when DM policy is 'allowlist'. Add '*' for open access. Does not affect admin routing \u2014 use adminPhones for that."),
|
|
1744
1827
|
sendReadReceipts: z.boolean().optional().default(true).describe("Whether to send read receipts (blue ticks) when messages are received. Disabling may feel less responsive but preserves privacy."),
|
|
1745
1828
|
mediaMaxMb: z.number().int().positive().optional().default(50).describe("Maximum file size in MB for media the agent will download and process."),
|
|
@@ -2630,16 +2713,21 @@ function extractMessage(msg) {
|
|
|
2630
2713
|
}
|
|
2631
2714
|
|
|
2632
2715
|
// app/lib/whatsapp/managed-account.ts
|
|
2716
|
+
function normalizeEntry(v) {
|
|
2717
|
+
return typeof v === "string" ? { account: v, mode: "active" } : { account: v.managesAccount, mode: v.mode ?? "active" };
|
|
2718
|
+
}
|
|
2633
2719
|
function managedAccountFor(accountManagers, phone) {
|
|
2634
|
-
for (const [managerPhone,
|
|
2635
|
-
|
|
2720
|
+
for (const [managerPhone, entry] of Object.entries(accountManagers)) {
|
|
2721
|
+
const { account, mode } = normalizeEntry(entry);
|
|
2722
|
+
if (account && phonesMatch(managerPhone, phone)) return { account, mode };
|
|
2636
2723
|
}
|
|
2637
2724
|
return null;
|
|
2638
2725
|
}
|
|
2639
2726
|
function managerPhonesForAccount(accountManagers, subAccountId) {
|
|
2640
2727
|
const phones = [];
|
|
2641
|
-
for (const [managerPhone,
|
|
2642
|
-
|
|
2728
|
+
for (const [managerPhone, entry] of Object.entries(accountManagers)) {
|
|
2729
|
+
const { account } = normalizeEntry(entry);
|
|
2730
|
+
if (account && account === subAccountId) phones.push(managerPhone);
|
|
2643
2731
|
}
|
|
2644
2732
|
return phones;
|
|
2645
2733
|
}
|
|
@@ -2670,12 +2758,12 @@ function checkDmAccess(params) {
|
|
|
2670
2758
|
if (isAdminPhone(senderPhone, cfg.adminPhones)) {
|
|
2671
2759
|
return { allowed: true, reason: "admin-binding", agentType: "admin", effectiveAccountId: accountId };
|
|
2672
2760
|
}
|
|
2673
|
-
const
|
|
2674
|
-
if (
|
|
2675
|
-
if (params.isValidAccount && !params.isValidAccount(
|
|
2761
|
+
const managed = managedAccountFor(cfg.accountManagers, senderPhone);
|
|
2762
|
+
if (managed) {
|
|
2763
|
+
if (params.isValidAccount && !params.isValidAccount(managed.account)) {
|
|
2676
2764
|
return { allowed: false, reason: "account-manager-unresolved", agentType: "admin" };
|
|
2677
2765
|
}
|
|
2678
|
-
return { allowed: true, reason: "account-manager", agentType: "admin", effectiveAccountId:
|
|
2766
|
+
return { allowed: true, reason: "account-manager", agentType: "admin", effectiveAccountId: managed.account, passive: managed.mode === "passive" };
|
|
2679
2767
|
}
|
|
2680
2768
|
switch (cfg.dmPolicy) {
|
|
2681
2769
|
case "open":
|
|
@@ -4867,6 +4955,7 @@ async function handleInboundMessage(conn, msg) {
|
|
|
4867
4955
|
const payload = {
|
|
4868
4956
|
accountId: conn.accountId,
|
|
4869
4957
|
agentType: accessResult.agentType,
|
|
4958
|
+
passive: accessResult.passive === true,
|
|
4870
4959
|
personId: accessResult.personId ?? null,
|
|
4871
4960
|
senderPhone,
|
|
4872
4961
|
text: extracted.text,
|
|
@@ -6192,6 +6281,9 @@ function createScheduleInjectRoutes(deps) {
|
|
|
6192
6281
|
return app57;
|
|
6193
6282
|
}
|
|
6194
6283
|
|
|
6284
|
+
// server/index.ts
|
|
6285
|
+
var import_dist8 = __toESM(require_dist(), 1);
|
|
6286
|
+
|
|
6195
6287
|
// app/lib/telegram/outbound/send-text.ts
|
|
6196
6288
|
async function sendTelegramText(botToken, chatId, text) {
|
|
6197
6289
|
try {
|
|
@@ -6414,7 +6506,7 @@ function purgeNonSocketAdminPhonesAtBoot() {
|
|
|
6414
6506
|
purgeNonSocketAdminPhones(acct.accountDir, socketOwner);
|
|
6415
6507
|
}
|
|
6416
6508
|
}
|
|
6417
|
-
function setAccountManager(accountDir, phone, subAccountId) {
|
|
6509
|
+
function setAccountManager(accountDir, phone, subAccountId, mode = "active") {
|
|
6418
6510
|
const normalized = phone.trim();
|
|
6419
6511
|
if (!E164_PATTERN.test(normalized)) {
|
|
6420
6512
|
return { ok: false, error: `Invalid phone format "${normalized}". Expected E.164 (e.g. +441234567890).` };
|
|
@@ -6448,7 +6540,7 @@ function setAccountManager(accountDir, phone, subAccountId) {
|
|
|
6448
6540
|
if (!wa.accountManagers || typeof wa.accountManagers !== "object") {
|
|
6449
6541
|
wa.accountManagers = {};
|
|
6450
6542
|
}
|
|
6451
|
-
wa.accountManagers[normalized] = sub;
|
|
6543
|
+
wa.accountManagers[normalized] = mode === "passive" ? { managesAccount: sub, mode: "passive" } : sub;
|
|
6452
6544
|
const parsed = WhatsAppConfigSchema.safeParse(wa);
|
|
6453
6545
|
if (!parsed.success) {
|
|
6454
6546
|
const msg = parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ");
|
|
@@ -6456,9 +6548,10 @@ function setAccountManager(accountDir, phone, subAccountId) {
|
|
|
6456
6548
|
}
|
|
6457
6549
|
config.whatsapp = parsed.data;
|
|
6458
6550
|
writeConfig(accountDir, config);
|
|
6459
|
-
console.error(`${TAG17} bound account manager phone=${normalized} managesAccount=${sub}`);
|
|
6551
|
+
console.error(`${TAG17} bound account manager phone=${normalized} managesAccount=${sub} mode=${mode}`);
|
|
6460
6552
|
reloadManagerConfig(accountDir);
|
|
6461
|
-
|
|
6553
|
+
const behaviour = mode === "passive" ? `Their WhatsApp messages will each file one task scoped to that sub-account; the agent sends nothing back.` : `Their WhatsApp messages will reach that sub-account's admin agent; replies still go out over this account's WhatsApp device.`;
|
|
6554
|
+
return { ok: true, message: `Bound ${normalized} as ${mode} account manager for sub-account ${sub}. ${behaviour}` };
|
|
6462
6555
|
} catch (err) {
|
|
6463
6556
|
const msg = err instanceof Error ? err.message : String(err);
|
|
6464
6557
|
console.error(`${TAG17} setAccountManager failed: ${msg}`);
|
|
@@ -6503,6 +6596,12 @@ function readAccountManagers(accountDir) {
|
|
|
6503
6596
|
const out = {};
|
|
6504
6597
|
for (const [k, v] of Object.entries(wa.accountManagers)) {
|
|
6505
6598
|
if (typeof v === "string") out[k] = v;
|
|
6599
|
+
else if (v && typeof v === "object" && typeof v.managesAccount === "string") {
|
|
6600
|
+
const obj = v;
|
|
6601
|
+
const rawMode = obj.mode;
|
|
6602
|
+
const mode = rawMode === void 0 ? void 0 : rawMode === "active" ? "active" : rawMode === "passive" ? "passive" : "passive";
|
|
6603
|
+
out[k] = { managesAccount: obj.managesAccount, mode };
|
|
6604
|
+
}
|
|
6506
6605
|
}
|
|
6507
6606
|
return out;
|
|
6508
6607
|
} catch {
|
|
@@ -7272,7 +7371,7 @@ app2.post("/reconnect", async (c) => {
|
|
|
7272
7371
|
app2.post("/config", async (c) => {
|
|
7273
7372
|
try {
|
|
7274
7373
|
const body = await c.req.json().catch(() => ({}));
|
|
7275
|
-
const { action, phone, slug, fields, accountId, managesAccount } = body;
|
|
7374
|
+
const { action, phone, slug, fields, accountId, managesAccount, mode } = body;
|
|
7276
7375
|
if (!action || typeof action !== "string") {
|
|
7277
7376
|
return c.json({ ok: false, error: 'Missing required field "action".' }, 400);
|
|
7278
7377
|
}
|
|
@@ -7310,8 +7409,9 @@ app2.post("/config", async (c) => {
|
|
|
7310
7409
|
if (!managesAccount || typeof managesAccount !== "string") {
|
|
7311
7410
|
return c.json({ ok: false, error: 'Missing required field "managesAccount" (the sub-account UUID this phone should manage).' }, 400);
|
|
7312
7411
|
}
|
|
7313
|
-
const
|
|
7314
|
-
|
|
7412
|
+
const managerMode = mode === "passive" ? "passive" : "active";
|
|
7413
|
+
const result = setAccountManager(account.accountDir, phone, managesAccount, managerMode);
|
|
7414
|
+
console.error(`${TAG21} config action=add-account-manager phone=${phone} managesAccount=${managesAccount} mode=${managerMode} ok=${result.ok}`);
|
|
7315
7415
|
return c.json(result, result.ok ? 200 : 400);
|
|
7316
7416
|
}
|
|
7317
7417
|
case "remove-account-manager": {
|
|
@@ -15000,7 +15100,7 @@ app21.post("/rename", requireAdminSession, async (c) => {
|
|
|
15000
15100
|
var files_default = app21;
|
|
15001
15101
|
|
|
15002
15102
|
// ../lib/graph-search/src/index.ts
|
|
15003
|
-
var import_dist = __toESM(
|
|
15103
|
+
var import_dist = __toESM(require_dist2());
|
|
15004
15104
|
import { int } from "neo4j-driver";
|
|
15005
15105
|
|
|
15006
15106
|
// ../lib/graph-search/src/rrf-fusion.ts
|
|
@@ -15898,8 +15998,8 @@ var graph_search_default = app22;
|
|
|
15898
15998
|
import neo4j2 from "neo4j-driver";
|
|
15899
15999
|
|
|
15900
16000
|
// app/lib/graph-labels.ts
|
|
15901
|
-
var import_dist2 = __toESM(
|
|
15902
|
-
var import_dist3 = __toESM(
|
|
16001
|
+
var import_dist2 = __toESM(require_dist3(), 1);
|
|
16002
|
+
var import_dist3 = __toESM(require_dist3(), 1);
|
|
15903
16003
|
var HIDDEN_BY_DEFAULT_LABELS = Object.freeze(
|
|
15904
16004
|
/* @__PURE__ */ new Set(["Chunk", "GraphPreference"])
|
|
15905
16005
|
);
|
|
@@ -17950,7 +18050,10 @@ async function managerSpawn(opts) {
|
|
|
17950
18050
|
visitorId: opts.visitorId,
|
|
17951
18051
|
name: opts.name,
|
|
17952
18052
|
webchatChannel: opts.webchatChannel,
|
|
17953
|
-
previousContext: opts.previousContext
|
|
18053
|
+
previousContext: opts.previousContext,
|
|
18054
|
+
initialMessage: opts.initialMessage,
|
|
18055
|
+
passive: opts.passive,
|
|
18056
|
+
targetAccountId: opts.targetAccountId
|
|
17954
18057
|
})
|
|
17955
18058
|
}).catch((err) => ({ __throw: err instanceof Error ? err.message : String(err) }));
|
|
17956
18059
|
if ("__throw" in res) {
|
|
@@ -20438,7 +20541,7 @@ app55.get("/free-busy", async (c) => {
|
|
|
20438
20541
|
var calendar_public_default = app55;
|
|
20439
20542
|
|
|
20440
20543
|
// app/lib/graph-health.ts
|
|
20441
|
-
var import_dist4 = __toESM(
|
|
20544
|
+
var import_dist4 = __toESM(require_dist4(), 1);
|
|
20442
20545
|
var HOUR_MS = 60 * 60 * 1e3;
|
|
20443
20546
|
function renderLabelTop(rows) {
|
|
20444
20547
|
return rows.map((b) => {
|
|
@@ -21050,6 +21153,9 @@ var InboundHub = class {
|
|
|
21050
21153
|
}
|
|
21051
21154
|
};
|
|
21052
21155
|
|
|
21156
|
+
// app/lib/whatsapp/gateway/wa-gateway.ts
|
|
21157
|
+
var import_dist5 = __toESM(require_dist(), 1);
|
|
21158
|
+
|
|
21053
21159
|
// node_modules/hono/dist/utils/stream.js
|
|
21054
21160
|
var StreamingApi = class {
|
|
21055
21161
|
writer;
|
|
@@ -21380,6 +21486,23 @@ var WaGateway = class {
|
|
|
21380
21486
|
}
|
|
21381
21487
|
/** Handle one inbound admin WhatsApp message. */
|
|
21382
21488
|
async handleInbound(input) {
|
|
21489
|
+
if (input.passive) {
|
|
21490
|
+
const msgId = `wa-${++this.seq}`;
|
|
21491
|
+
await this.deps.ensureChannelSession({
|
|
21492
|
+
accountId: input.accountId,
|
|
21493
|
+
effectiveAccountId: input.effectiveAccountId,
|
|
21494
|
+
senderId: input.senderId,
|
|
21495
|
+
// agentType stays 'admin'; the constraint rides the passive flag.
|
|
21496
|
+
role: "admin",
|
|
21497
|
+
personId: null,
|
|
21498
|
+
gatewayUrl: this.deps.gatewayUrl,
|
|
21499
|
+
serverPath: this.deps.serverPath,
|
|
21500
|
+
passive: true,
|
|
21501
|
+
text: input.text,
|
|
21502
|
+
msgId
|
|
21503
|
+
});
|
|
21504
|
+
return;
|
|
21505
|
+
}
|
|
21383
21506
|
const bytes = Buffer.byteLength(input.text, "utf8");
|
|
21384
21507
|
const hadSubscriber = this.hub.hasSubscriber(input.senderId);
|
|
21385
21508
|
const willDeliverNow = this.hub.isReady(input.senderId);
|
|
@@ -21388,13 +21511,22 @@ var WaGateway = class {
|
|
|
21388
21511
|
const source = input.source ?? "user";
|
|
21389
21512
|
this.replies.set(input.senderId, input.reply);
|
|
21390
21513
|
this.docContexts.set(input.senderId, { accountId: input.accountId, maxyAccountId: input.effectiveAccountId });
|
|
21514
|
+
let standingRules;
|
|
21515
|
+
if (this.deps.fetchStandingRules) {
|
|
21516
|
+
standingRules = await this.deps.fetchStandingRules(input.effectiveAccountId) || void 0;
|
|
21517
|
+
const injected = standingRules ? (standingRules.match(/^- /gm) ?? []).length : 0;
|
|
21518
|
+
console.error(
|
|
21519
|
+
`[preference-inject] op=inject channel=wa accountId=${input.effectiveAccountId} injected=${injected} capped=${injected >= import_dist5.INJECTION_RULE_CAP}`
|
|
21520
|
+
);
|
|
21521
|
+
}
|
|
21391
21522
|
this.hub.deliver(
|
|
21392
21523
|
{
|
|
21393
21524
|
senderId: input.senderId,
|
|
21394
21525
|
text: input.text,
|
|
21395
21526
|
waMessageId: `wa-${++this.seq}`,
|
|
21396
21527
|
media: input.media,
|
|
21397
|
-
source
|
|
21528
|
+
source,
|
|
21529
|
+
standingRules
|
|
21398
21530
|
},
|
|
21399
21531
|
Date.now()
|
|
21400
21532
|
);
|
|
@@ -21455,8 +21587,8 @@ function buildWaSpawnRequest(input) {
|
|
|
21455
21587
|
|
|
21456
21588
|
// app/lib/whatsapp/inbound/route-decision.ts
|
|
21457
21589
|
function decideWaRoute(msg) {
|
|
21458
|
-
if (msg.agentType === "admin") return { action: "route", role: "admin", personId: null };
|
|
21459
|
-
if (msg.personId && msg.personId.length > 0) return { action: "route", role: "public", personId: msg.personId };
|
|
21590
|
+
if (msg.agentType === "admin") return { action: "route", role: "admin", personId: null, passive: msg.passive === true };
|
|
21591
|
+
if (msg.personId && msg.personId.length > 0) return { action: "route", role: "public", personId: msg.personId, passive: false };
|
|
21460
21592
|
return { action: "drop", reason: "public-unresolved" };
|
|
21461
21593
|
}
|
|
21462
21594
|
|
|
@@ -21617,6 +21749,9 @@ var InboundHub2 = class {
|
|
|
21617
21749
|
}
|
|
21618
21750
|
};
|
|
21619
21751
|
|
|
21752
|
+
// app/lib/webchat/gateway/webchat-gateway.ts
|
|
21753
|
+
var import_dist6 = __toESM(require_dist(), 1);
|
|
21754
|
+
|
|
21620
21755
|
// app/lib/webchat/gateway/routes.ts
|
|
21621
21756
|
function createWebchatChannelRoutes(deps) {
|
|
21622
21757
|
const app57 = new Hono();
|
|
@@ -22051,8 +22186,16 @@ var WebchatGateway = class _WebchatGateway {
|
|
|
22051
22186
|
const bytes = Buffer.byteLength(input.text, "utf8");
|
|
22052
22187
|
const hadSubscriber = this.hub.hasSubscriber(input.key);
|
|
22053
22188
|
const willDeliverNow = this.hub.isReady(input.key);
|
|
22189
|
+
let standingRules;
|
|
22190
|
+
if (input.role === "admin" && this.deps.fetchStandingRules) {
|
|
22191
|
+
standingRules = await this.deps.fetchStandingRules(input.accountId) || void 0;
|
|
22192
|
+
const injected = standingRules ? (standingRules.match(/^- /gm) ?? []).length : 0;
|
|
22193
|
+
console.error(
|
|
22194
|
+
`[preference-inject] op=inject channel=web accountId=${input.accountId} injected=${injected} capped=${injected >= import_dist6.INJECTION_RULE_CAP}`
|
|
22195
|
+
);
|
|
22196
|
+
}
|
|
22054
22197
|
this.hub.deliver(
|
|
22055
|
-
{ key: input.key, text: input.text, messageId: `wc-${++this.seq}
|
|
22198
|
+
{ key: input.key, text: input.text, messageId: `wc-${++this.seq}`, standingRules },
|
|
22056
22199
|
Date.now()
|
|
22057
22200
|
);
|
|
22058
22201
|
if (willDeliverNow) this.lastDeliveredAt.set(input.key, Date.now());
|
|
@@ -22570,6 +22713,9 @@ var InboundHub3 = class {
|
|
|
22570
22713
|
}
|
|
22571
22714
|
};
|
|
22572
22715
|
|
|
22716
|
+
// app/lib/telegram/gateway/telegram-gateway.ts
|
|
22717
|
+
var import_dist7 = __toESM(require_dist(), 1);
|
|
22718
|
+
|
|
22573
22719
|
// app/lib/telegram/gateway/routes.ts
|
|
22574
22720
|
function createTelegramChannelRoutes(deps) {
|
|
22575
22721
|
const app57 = new Hono();
|
|
@@ -22700,8 +22846,16 @@ var TelegramGateway = class {
|
|
|
22700
22846
|
const willDeliverNow = this.hub.isReady(input.senderId);
|
|
22701
22847
|
const source = input.source ?? "user";
|
|
22702
22848
|
this.replies.set(input.senderId, input.reply);
|
|
22849
|
+
let standingRules;
|
|
22850
|
+
if (input.role === "admin" && this.deps.fetchStandingRules) {
|
|
22851
|
+
standingRules = await this.deps.fetchStandingRules(input.accountId) || void 0;
|
|
22852
|
+
const injected = standingRules ? (standingRules.match(/^- /gm) ?? []).length : 0;
|
|
22853
|
+
console.error(
|
|
22854
|
+
`[preference-inject] op=inject channel=tg accountId=${input.accountId} injected=${injected} capped=${injected >= import_dist7.INJECTION_RULE_CAP}`
|
|
22855
|
+
);
|
|
22856
|
+
}
|
|
22703
22857
|
this.hub.deliver(
|
|
22704
|
-
{ key: input.senderId, text: input.text, messageId: `tg-${++this.seq}`, source },
|
|
22858
|
+
{ key: input.senderId, text: input.text, messageId: `tg-${++this.seq}`, source, standingRules },
|
|
22705
22859
|
Date.now()
|
|
22706
22860
|
);
|
|
22707
22861
|
console.error(
|
|
@@ -23057,7 +23211,8 @@ async function firePublicSessionEndReview(input) {
|
|
|
23057
23211
|
// app/lib/whatsapp/inbound/channel-admin-binding-drift.ts
|
|
23058
23212
|
function findAccountManagerDrift(accountManagers, adminPhones, validAccountIds) {
|
|
23059
23213
|
const drift = [];
|
|
23060
|
-
for (const [phone,
|
|
23214
|
+
for (const [phone, entry] of Object.entries(accountManagers)) {
|
|
23215
|
+
const managesAccount = typeof entry === "string" ? entry : entry.managesAccount;
|
|
23061
23216
|
if (!validAccountIds.includes(managesAccount)) {
|
|
23062
23217
|
drift.push({ phone, managesAccount, reason: "not-in-registry" });
|
|
23063
23218
|
} else if (adminPhones.some((a) => phonesMatch(a, phone))) {
|
|
@@ -23466,7 +23621,22 @@ function isPublicHost(host) {
|
|
|
23466
23621
|
}
|
|
23467
23622
|
var app56 = new Hono();
|
|
23468
23623
|
var nativeFileFollowers = /* @__PURE__ */ new Map();
|
|
23624
|
+
async function fetchAccountStandingRules(accountId) {
|
|
23625
|
+
const session = getSession();
|
|
23626
|
+
try {
|
|
23627
|
+
const rules = await (0, import_dist8.activeRuleSet)(session, accountId);
|
|
23628
|
+
return (0, import_dist8.formatStandingRulesBlock)(rules);
|
|
23629
|
+
} catch (err) {
|
|
23630
|
+
console.error(
|
|
23631
|
+
`[preference-inject] op=fetch-failed accountId=${accountId} error=${err instanceof Error ? err.message : String(err)}`
|
|
23632
|
+
);
|
|
23633
|
+
return "";
|
|
23634
|
+
} finally {
|
|
23635
|
+
await session.close();
|
|
23636
|
+
}
|
|
23637
|
+
}
|
|
23469
23638
|
var waGateway = new WaGateway({
|
|
23639
|
+
fetchStandingRules: fetchAccountStandingRules,
|
|
23470
23640
|
gatewayUrl: `http://127.0.0.1:${process.env.MAXY_UI_INTERNAL_PORT ?? ""}`,
|
|
23471
23641
|
serverPath: process.env.MAXY_WA_CHANNEL_SERVER_PATH ?? resolve33(process.env.MAXY_PLATFORM_ROOT ?? join35(__dirname, ".."), "services/whatsapp-channel/dist/server.js"),
|
|
23472
23642
|
// Task 751 / 1390 — file delivery on the native channel. `maxyAccountId` (the
|
|
@@ -23487,7 +23657,30 @@ var waGateway = new WaGateway({
|
|
|
23487
23657
|
});
|
|
23488
23658
|
return result.ok ? { ok: true, messageId: result.messageId } : { ok: false, error: result.error };
|
|
23489
23659
|
},
|
|
23490
|
-
ensureChannelSession: async ({ accountId, effectiveAccountId, senderId, role, personId, gatewayUrl, serverPath }) => {
|
|
23660
|
+
ensureChannelSession: async ({ accountId, effectiveAccountId, senderId, role, personId, gatewayUrl, serverPath, passive, text, msgId }) => {
|
|
23661
|
+
if (passive) {
|
|
23662
|
+
const phoneHash = createHash6("sha256").update(senderId).digest("hex").slice(0, 12);
|
|
23663
|
+
const prompt = (text ?? "").trim();
|
|
23664
|
+
if (prompt.length === 0) {
|
|
23665
|
+
console.error(`[wa-passive] op=dropped account=${effectiveAccountId} phoneHash=${phoneHash} msgId=${msgId ?? "none"} reason=empty-text`);
|
|
23666
|
+
return;
|
|
23667
|
+
}
|
|
23668
|
+
console.error(`[wa-passive] op=dispatch account=${effectiveAccountId} phoneHash=${phoneHash} msgId=${msgId ?? "none"}`);
|
|
23669
|
+
const result2 = await managerSpawn({
|
|
23670
|
+
senderId,
|
|
23671
|
+
role: "public",
|
|
23672
|
+
channel: "whatsapp",
|
|
23673
|
+
accountId: effectiveAccountId,
|
|
23674
|
+
targetAccountId: effectiveAccountId,
|
|
23675
|
+
agentSlug: "passive",
|
|
23676
|
+
initialMessage: prompt,
|
|
23677
|
+
passive: true
|
|
23678
|
+
});
|
|
23679
|
+
if ("error" in result2) {
|
|
23680
|
+
console.error(`[wa-passive] op=dispatch-failed account=${effectiveAccountId} msgId=${msgId ?? "none"} error=${result2.error}`);
|
|
23681
|
+
}
|
|
23682
|
+
return;
|
|
23683
|
+
}
|
|
23491
23684
|
if (role === "admin") {
|
|
23492
23685
|
const managesAccount = effectiveAccountId !== accountId ? effectiveAccountId : "none";
|
|
23493
23686
|
console.error(`[whatsapp-native] op=account-manager-route senderId=${senderId} managesAccount=${managesAccount} effectiveAccount=${effectiveAccountId} source=gate`);
|
|
@@ -23524,6 +23717,7 @@ var waGateway = new WaGateway({
|
|
|
23524
23717
|
app56.route("/", waGateway.routes());
|
|
23525
23718
|
waGateway.startSweeper();
|
|
23526
23719
|
var webchatGateway = new WebchatGateway({
|
|
23720
|
+
fetchStandingRules: fetchAccountStandingRules,
|
|
23527
23721
|
gatewayUrl: webchatGatewayUrl(),
|
|
23528
23722
|
serverPath: webchatServerPath(),
|
|
23529
23723
|
ensureChannelSession: async ({ accountId, key, role, adminUserId, gatewayUrl, serverPath, sessionId, public: pub }) => {
|
|
@@ -23609,6 +23803,7 @@ webchatGateway.startSweeper();
|
|
|
23609
23803
|
webchatGateway.startPublicReaper();
|
|
23610
23804
|
var telegramFileFollowers = /* @__PURE__ */ new Map();
|
|
23611
23805
|
var telegramGateway = new TelegramGateway({
|
|
23806
|
+
fetchStandingRules: fetchAccountStandingRules,
|
|
23612
23807
|
gatewayUrl: telegramGatewayUrl(),
|
|
23613
23808
|
serverPath: telegramServerPath(),
|
|
23614
23809
|
ensureChannelSession: async ({ accountId, senderId, role, personId, chatId, gatewayUrl, serverPath }) => {
|
|
@@ -23663,10 +23858,11 @@ var scheduleInjectRoutes = createScheduleInjectRoutes({
|
|
|
23663
23858
|
if (!sent.ok) throw new Error(sent.error ?? "telegram send failed");
|
|
23664
23859
|
},
|
|
23665
23860
|
effectiveAccountFor: (accountId, accountDir, destination) => {
|
|
23666
|
-
const
|
|
23667
|
-
if (
|
|
23668
|
-
if (
|
|
23669
|
-
return
|
|
23861
|
+
const managed = managedAccountFor(readAccountManagers(accountDir), destination);
|
|
23862
|
+
if (managed === null) return accountId;
|
|
23863
|
+
if (managed.mode === "passive") return null;
|
|
23864
|
+
if (!isValidAccountId(managed.account)) return null;
|
|
23865
|
+
return managed.account;
|
|
23670
23866
|
}
|
|
23671
23867
|
});
|
|
23672
23868
|
app56.route("/api/channel/schedule-inject", scheduleInjectRoutes);
|
|
@@ -24716,7 +24912,7 @@ init({
|
|
|
24716
24912
|
console.error(`[whatsapp:route] skipped reason=owner-mirror senderId=${msg.senderPhone}`);
|
|
24717
24913
|
return;
|
|
24718
24914
|
}
|
|
24719
|
-
const decision = decideWaRoute(msg);
|
|
24915
|
+
const decision = decideWaRoute({ agentType: msg.agentType, personId: msg.personId, passive: msg.passive });
|
|
24720
24916
|
if (decision.action === "drop") {
|
|
24721
24917
|
console.error(`[whatsapp:route] op=dropped reason=${decision.reason} senderId=${msg.senderPhone}`);
|
|
24722
24918
|
return;
|
|
@@ -24734,7 +24930,7 @@ init({
|
|
|
24734
24930
|
console.error(`[whatsapp:route] op=routed agentType=public personId=${decision.personId} senderId=${msg.senderPhone}`);
|
|
24735
24931
|
}
|
|
24736
24932
|
try {
|
|
24737
|
-
void msg.composing().catch(() => {
|
|
24933
|
+
if (!decision.passive) void msg.composing().catch(() => {
|
|
24738
24934
|
});
|
|
24739
24935
|
await waGateway.handleInbound({
|
|
24740
24936
|
accountId: msg.accountId,
|
|
@@ -24742,6 +24938,9 @@ init({
|
|
|
24742
24938
|
senderId: msg.senderPhone,
|
|
24743
24939
|
role: decision.role,
|
|
24744
24940
|
personId: decision.personId,
|
|
24941
|
+
// Task 1483 — a passive account-manager inbound routes to a fresh
|
|
24942
|
+
// constrained one-shot spawn instead of the shared rc-daemon path.
|
|
24943
|
+
passive: decision.passive,
|
|
24745
24944
|
text: msg.text,
|
|
24746
24945
|
reply: msg.reply,
|
|
24747
24946
|
media: msg.media
|