@rubytech/create-realagent-code 0.1.254 → 0.1.255

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.
Files changed (158) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/.docs/search-surface-contract.md +58 -0
  3. package/payload/platform/lib/embed-client/dist/index.d.ts +4 -0
  4. package/payload/platform/lib/embed-client/dist/index.d.ts.map +1 -0
  5. package/payload/platform/lib/embed-client/dist/index.js +53 -0
  6. package/payload/platform/lib/embed-client/dist/index.js.map +1 -0
  7. package/payload/platform/lib/embed-client/src/index.ts +53 -0
  8. package/payload/platform/lib/embed-client/tsconfig.json +8 -0
  9. package/payload/platform/lib/graph-search/dist/index.d.ts +27 -6
  10. package/payload/platform/lib/graph-search/dist/index.d.ts.map +1 -1
  11. package/payload/platform/lib/graph-search/dist/index.js +19 -1
  12. package/payload/platform/lib/graph-search/dist/index.js.map +1 -1
  13. package/payload/platform/lib/graph-search/src/index.ts +28 -6
  14. package/payload/platform/lib/graph-write/dist/index.d.ts +25 -0
  15. package/payload/platform/lib/graph-write/dist/index.d.ts.map +1 -1
  16. package/payload/platform/lib/graph-write/dist/index.js +78 -2
  17. package/payload/platform/lib/graph-write/dist/index.js.map +1 -1
  18. package/payload/platform/lib/graph-write/src/index.ts +96 -1
  19. package/payload/platform/package.json +2 -2
  20. package/payload/platform/plugins/admin/.claude-plugin/plugin.json +1 -1
  21. package/payload/platform/plugins/admin/PLUGIN.md +3 -3
  22. package/payload/platform/plugins/admin/hooks/__tests__/{session-end-retrospective.test.sh → insight.test.sh} +152 -153
  23. package/payload/platform/plugins/admin/hooks/insight.sh +219 -0
  24. package/payload/platform/plugins/admin/hooks/lib/admin-graph-pass-common.sh +5 -5
  25. package/payload/platform/plugins/admin/mcp/dist/index.js +33 -19
  26. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  27. package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +23 -23
  28. package/payload/platform/plugins/docs/references/graph.md +2 -0
  29. package/payload/platform/plugins/docs/references/internals.md +12 -1
  30. package/payload/platform/plugins/docs/references/neo4j.md +2 -2
  31. package/payload/platform/plugins/docs/references/platform.md +1 -1
  32. package/payload/platform/plugins/docs/references/session-retrospective.md +5 -18
  33. package/payload/platform/plugins/email/PLUGIN.md +2 -2
  34. package/payload/platform/plugins/email/mcp/dist/index.js +8 -0
  35. package/payload/platform/plugins/email/mcp/dist/index.js.map +1 -1
  36. package/payload/platform/plugins/email/mcp/dist/lib/attachment-resolve.d.ts +19 -0
  37. package/payload/platform/plugins/email/mcp/dist/lib/attachment-resolve.d.ts.map +1 -0
  38. package/payload/platform/plugins/email/mcp/dist/lib/attachment-resolve.js +64 -0
  39. package/payload/platform/plugins/email/mcp/dist/lib/attachment-resolve.js.map +1 -0
  40. package/payload/platform/plugins/email/mcp/dist/lib/smtp.d.ts +4 -0
  41. package/payload/platform/plugins/email/mcp/dist/lib/smtp.d.ts.map +1 -1
  42. package/payload/platform/plugins/email/mcp/dist/lib/smtp.js +1 -0
  43. package/payload/platform/plugins/email/mcp/dist/lib/smtp.js.map +1 -1
  44. package/payload/platform/plugins/email/mcp/dist/tools/email-reply.d.ts +1 -0
  45. package/payload/platform/plugins/email/mcp/dist/tools/email-reply.d.ts.map +1 -1
  46. package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js +6 -1
  47. package/payload/platform/plugins/email/mcp/dist/tools/email-reply.js.map +1 -1
  48. package/payload/platform/plugins/email/mcp/dist/tools/email-send.d.ts +1 -0
  49. package/payload/platform/plugins/email/mcp/dist/tools/email-send.d.ts.map +1 -1
  50. package/payload/platform/plugins/email/mcp/dist/tools/email-send.js +7 -1
  51. package/payload/platform/plugins/email/mcp/dist/tools/email-send.js.map +1 -1
  52. package/payload/platform/plugins/email/references/email-reference.md +4 -0
  53. package/payload/platform/plugins/memory/PLUGIN.md +1 -2
  54. package/payload/platform/plugins/memory/mcp/dist/index.js +5 -43
  55. package/payload/platform/plugins/memory/mcp/dist/index.js.map +1 -1
  56. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/document-sectioniser.test.d.ts +2 -0
  57. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/document-sectioniser.test.d.ts.map +1 -0
  58. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/document-sectioniser.test.js +41 -0
  59. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/document-sectioniser.test.js.map +1 -0
  60. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-embed-net.test.d.ts +2 -0
  61. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-embed-net.test.d.ts.map +1 -0
  62. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-embed-net.test.js +90 -0
  63. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/graph-write-embed-net.test.js.map +1 -0
  64. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/vector-indexed-labels-drift.test.d.ts +2 -0
  65. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/vector-indexed-labels-drift.test.d.ts.map +1 -0
  66. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/vector-indexed-labels-drift.test.js +27 -0
  67. package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/vector-indexed-labels-drift.test.js.map +1 -0
  68. package/payload/platform/plugins/memory/mcp/dist/lib/document-sectioniser.d.ts +10 -0
  69. package/payload/platform/plugins/memory/mcp/dist/lib/document-sectioniser.d.ts.map +1 -0
  70. package/payload/platform/plugins/memory/mcp/dist/lib/document-sectioniser.js +47 -0
  71. package/payload/platform/plugins/memory/mcp/dist/lib/document-sectioniser.js.map +1 -0
  72. package/payload/platform/plugins/memory/mcp/dist/lib/embeddings.d.ts +1 -2
  73. package/payload/platform/plugins/memory/mcp/dist/lib/embeddings.d.ts.map +1 -1
  74. package/payload/platform/plugins/memory/mcp/dist/lib/embeddings.js +5 -28
  75. package/payload/platform/plugins/memory/mcp/dist/lib/embeddings.js.map +1 -1
  76. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/build-text-representation-bound.test.d.ts +2 -0
  77. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/build-text-representation-bound.test.d.ts.map +1 -0
  78. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/build-text-representation-bound.test.js +20 -0
  79. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/build-text-representation-bound.test.js.map +1 -0
  80. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-preference-embed.test.d.ts +2 -0
  81. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-preference-embed.test.d.ts.map +1 -0
  82. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-preference-embed.test.js +67 -0
  83. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/conversation-archive-preference-embed.test.js.map +1 -0
  84. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.d.ts +2 -0
  85. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.d.ts.map +1 -0
  86. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.js +34 -0
  87. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/embeddings-cap.test.js.map +1 -0
  88. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-section-writer.test.d.ts +2 -0
  89. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-section-writer.test.d.ts.map +1 -0
  90. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-section-writer.test.js +61 -0
  91. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-section-writer.test.js.map +1 -0
  92. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write.test.js +23 -1
  93. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-archive-write.test.js.map +1 -1
  94. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex.test.d.ts +2 -0
  95. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex.test.d.ts.map +1 -0
  96. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex.test.js +87 -0
  97. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-reindex.test.js.map +1 -0
  98. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.js +3 -0
  99. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-fields.test.js.map +1 -1
  100. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-threshold.test.d.ts +2 -0
  101. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-threshold.test.d.ts.map +1 -0
  102. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-threshold.test.js +34 -0
  103. package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-search-threshold.test.js.map +1 -0
  104. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.d.ts.map +1 -1
  105. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js +19 -4
  106. package/payload/platform/plugins/memory/mcp/dist/tools/conversation-archive-derive-insights.js.map +1 -1
  107. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts +33 -6
  108. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.d.ts.map +1 -1
  109. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js +280 -10
  110. package/payload/platform/plugins/memory/mcp/dist/tools/memory-archive-write.js.map +1 -1
  111. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.d.ts.map +1 -1
  112. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.js +76 -37
  113. package/payload/platform/plugins/memory/mcp/dist/tools/memory-reindex.js.map +1 -1
  114. package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.d.ts.map +1 -1
  115. package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js +11 -2
  116. package/payload/platform/plugins/memory/mcp/dist/tools/memory-search.js.map +1 -1
  117. package/payload/platform/plugins/memory/mcp/dist/tools/memory-typed-edge-pass.d.ts +3 -3
  118. package/payload/platform/plugins/memory/mcp/dist/tools/memory-typed-edge-pass.js +2 -2
  119. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.d.ts.map +1 -1
  120. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js +10 -2
  121. package/payload/platform/plugins/memory/mcp/dist/tools/memory-write.js.map +1 -1
  122. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +6 -3
  123. package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
  124. package/payload/platform/plugins/memory/mcp/vitest.config.ts +5 -0
  125. package/payload/platform/plugins/memory/references/schema-base.md +1 -1
  126. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics-graph-ingest.d.ts.map +1 -1
  127. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics-graph-ingest.js +15 -0
  128. package/payload/platform/plugins/scheduling/mcp/dist/lib/ics-graph-ingest.js.map +1 -1
  129. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js +4 -0
  130. package/payload/platform/plugins/workflows/mcp/dist/tools/workflow-execute.js.map +1 -1
  131. package/payload/platform/scripts/identity-forbidden-token-check.mjs +0 -1
  132. package/payload/platform/scripts/setup-account.sh +2 -8
  133. package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.d.ts +23 -0
  134. package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.d.ts.map +1 -0
  135. package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.js +29 -0
  136. package/payload/platform/services/claude-session-manager/dist/agent-identity-locator.js.map +1 -0
  137. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.d.ts.map +1 -1
  138. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js +0 -1
  139. package/payload/platform/services/claude-session-manager/dist/canonical-tool-names.generated.js.map +1 -1
  140. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  141. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +8 -1
  142. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  143. package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.d.ts +13 -1
  144. package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.d.ts.map +1 -1
  145. package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.js +26 -2
  146. package/payload/platform/services/claude-session-manager/dist/public-agent-reachability.js.map +1 -1
  147. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js +1 -1
  148. package/payload/platform/services/claude-session-manager/dist/rc-daemon.js.map +1 -1
  149. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts +12 -3
  150. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -1
  151. package/payload/platform/services/claude-session-manager/dist/system-prompt.js +3 -2
  152. package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
  153. package/payload/platform/templates/agents/admin/IDENTITY.md +2 -2
  154. package/payload/platform/templates/specialists/agents/database-operator.md +2 -6
  155. package/payload/server/{chunk-M6A6EZD4.js → chunk-76HRO7NX.js} +16 -2
  156. package/payload/server/maxy-edge.js +1 -1
  157. package/payload/server/server.js +473 -28
  158. package/payload/platform/plugins/admin/hooks/session-end-retrospective.sh +0 -214
@@ -93,7 +93,7 @@ import {
93
93
  vncLog,
94
94
  walkPremiumBundles,
95
95
  writeAdminUserAndPerson
96
- } from "./chunk-M6A6EZD4.js";
96
+ } from "./chunk-76HRO7NX.js";
97
97
  import {
98
98
  __commonJS,
99
99
  __require,
@@ -5211,6 +5211,374 @@ var require_dist3 = __commonJS({
5211
5211
  }
5212
5212
  });
5213
5213
 
5214
+ // ../lib/graph-write/dist/audit.js
5215
+ var require_audit = __commonJS({
5216
+ "../lib/graph-write/dist/audit.js"(exports) {
5217
+ "use strict";
5218
+ Object.defineProperty(exports, "__esModule", { value: true });
5219
+ exports.auditCypherWrite = auditCypherWrite;
5220
+ exports.formatAuditLine = formatAuditLine;
5221
+ var EDGE_PATTERN = /\[[^\]]*?:([A-Z_][A-Za-z0-9_]*(?:\|[A-Z_][A-Za-z0-9_]*)*)[^\]]*?\]/g;
5222
+ var CREATE_OR_MERGE_NODE = /\b(?:CREATE|MERGE)\s*\(\s*[A-Za-z_][A-Za-z0-9_]*\s*:\s*[A-Z]/g;
5223
+ var PROVENANCE_TOKEN = /\bcreatedBy(?:Agent|Tool|Session|Source)\b/g;
5224
+ function stripStringLiterals(cypher) {
5225
+ return cypher.replace(/'[^']*'|"[^"]*"/g, '""');
5226
+ }
5227
+ function extractEdgeTypes(cleaned) {
5228
+ const out = /* @__PURE__ */ new Set();
5229
+ for (const m of cleaned.matchAll(EDGE_PATTERN)) {
5230
+ for (const t of m[1].split("|")) {
5231
+ const clean = t.trim();
5232
+ if (clean)
5233
+ out.add(clean);
5234
+ }
5235
+ }
5236
+ return out;
5237
+ }
5238
+ function countCreateOrMergeNodes(cleaned) {
5239
+ const matches = cleaned.match(CREATE_OR_MERGE_NODE);
5240
+ return matches ? matches.length : 0;
5241
+ }
5242
+ function countProvenanceStamps(cleaned) {
5243
+ const matches = cleaned.match(PROVENANCE_TOKEN);
5244
+ return matches ? matches.length : 0;
5245
+ }
5246
+ function auditCypherWrite(input) {
5247
+ const warnings = [];
5248
+ const cleaned = stripStringLiterals(input.cypher);
5249
+ const referencedTypes = extractEdgeTypes(cleaned);
5250
+ for (const t of referencedTypes) {
5251
+ if (!input.schema.relationshipTypes.has(t)) {
5252
+ warnings.push({ kind: "unknown-type-warning", type: t });
5253
+ }
5254
+ }
5255
+ if (input.nodesCreated > 0) {
5256
+ const createOrMergeNodes = countCreateOrMergeNodes(cleaned);
5257
+ if (createOrMergeNodes > 0) {
5258
+ const stamps = countProvenanceStamps(cleaned);
5259
+ if (stamps < createOrMergeNodes) {
5260
+ warnings.push({
5261
+ kind: "missing-provenance-warning",
5262
+ created: createOrMergeNodes,
5263
+ stamped: stamps
5264
+ });
5265
+ }
5266
+ }
5267
+ }
5268
+ if (input.orphanIds.length > 0) {
5269
+ warnings.push({ kind: "orphan-warning", orphanIds: input.orphanIds });
5270
+ }
5271
+ return warnings;
5272
+ }
5273
+ function formatAuditLine(line) {
5274
+ const prefixField = `query="${line.cypherPrefix.replace(/"/g, "'")}"`;
5275
+ switch (line.kind) {
5276
+ case "accepted":
5277
+ return `[graph-cypher-write] accepted ${prefixField} nodesCreated=${line.nodesCreated} relsCreated=${line.relsCreated} agentName=${line.agentName} sessionId=${line.sessionId}`;
5278
+ case "orphan-warning":
5279
+ return `[graph-cypher-write] orphan-warning ${prefixField} orphanIds=${line.orphanIds.join(",")}`;
5280
+ case "unknown-type-warning":
5281
+ return `[graph-cypher-write] unknown-type-warning ${prefixField} type=${line.type}`;
5282
+ case "missing-provenance-warning":
5283
+ return `[graph-cypher-write] missing-provenance-warning ${prefixField} created=${line.created} stamped=${line.stamped}`;
5284
+ }
5285
+ }
5286
+ }
5287
+ });
5288
+
5289
+ // ../lib/graph-write/dist/conversation-provenance.js
5290
+ var require_conversation_provenance = __commonJS({
5291
+ "../lib/graph-write/dist/conversation-provenance.js"(exports) {
5292
+ "use strict";
5293
+ Object.defineProperty(exports, "__esModule", { value: true });
5294
+ exports.injectConversationProvenance = injectConversationProvenance;
5295
+ var index_js_1 = require_dist4();
5296
+ async function injectConversationProvenance(params) {
5297
+ const { session, relationships, accountId, writeLabels, conversationNodeId, logNamespace, tool } = params;
5298
+ const original = [...relationships];
5299
+ if (!writeLabels.some((l) => index_js_1.ACTION_PROVENANCE_LABELS.has(l)))
5300
+ return original;
5301
+ if (!conversationNodeId)
5302
+ return original;
5303
+ if (hasInboundProducedEdge(original))
5304
+ return original;
5305
+ let lookup;
5306
+ try {
5307
+ lookup = await session.run(`MATCH (c:Conversation {sessionId: $cid, accountId: $accountId})
5308
+ RETURN elementId(c) AS elementId, labels(c) AS labels LIMIT 1`, { cid: conversationNodeId, accountId });
5309
+ } catch (err) {
5310
+ process.stderr.write(`[${logNamespace}] [provenance-missing] tool=${tool} reason=driver-error message=${err instanceof Error ? err.message : String(err)} conversationNodeId=${conversationNodeId}
5311
+ `);
5312
+ return original;
5313
+ }
5314
+ if (lookup.records.length === 0) {
5315
+ process.stderr.write(`[${logNamespace}] [provenance-missing] tool=${tool} reason=node-not-found conversationNodeId=${conversationNodeId}
5316
+ `);
5317
+ return original;
5318
+ }
5319
+ const elementId = lookup.records[0].get("elementId");
5320
+ const labels = lookup.records[0].get("labels");
5321
+ const sourceLabel = labels.find((l) => index_js_1.PROVENANCE_SOURCE_LABELS.has(l));
5322
+ if (!sourceLabel) {
5323
+ process.stderr.write(`[${logNamespace}] [provenance-missing] tool=${tool} reason=wrong-source-label labels=${labels.join(",")} conversationNodeId=${conversationNodeId}
5324
+ `);
5325
+ return original;
5326
+ }
5327
+ process.stderr.write(`[${logNamespace}] [provenance-inject] tool=${tool} from=${sourceLabel}:${conversationNodeId}
5328
+ `);
5329
+ return [
5330
+ {
5331
+ type: "PRODUCED",
5332
+ direction: "incoming",
5333
+ targetNodeId: elementId
5334
+ },
5335
+ ...original
5336
+ ];
5337
+ }
5338
+ function hasInboundProducedEdge(relationships) {
5339
+ return relationships.some((r) => r.type === "PRODUCED" && r.direction === "incoming");
5340
+ }
5341
+ }
5342
+ });
5343
+
5344
+ // ../lib/graph-write/dist/index.js
5345
+ var require_dist4 = __commonJS({
5346
+ "../lib/graph-write/dist/index.js"(exports) {
5347
+ "use strict";
5348
+ var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m, k, k2) {
5349
+ if (k2 === void 0) k2 = k;
5350
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5351
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
5352
+ desc = { enumerable: true, get: function() {
5353
+ return m[k];
5354
+ } };
5355
+ }
5356
+ Object.defineProperty(o, k2, desc);
5357
+ }) : (function(o, m, k, k2) {
5358
+ if (k2 === void 0) k2 = k;
5359
+ o[k2] = m[k];
5360
+ }));
5361
+ var __exportStar = exports && exports.__exportStar || function(m, exports2) {
5362
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p)) __createBinding(exports2, m, p);
5363
+ };
5364
+ Object.defineProperty(exports, "__esModule", { value: true });
5365
+ exports.DOCUMENT_ARCHIVE_LABELS = exports.VECTOR_INDEXED_LABELS = exports.PROVENANCE_SOURCE_LABELS = exports.ACTION_PROVENANCE_LABELS = void 0;
5366
+ exports.stampCreatedBy = stampCreatedBy;
5367
+ exports.writeNodeWithEdges = writeNodeWithEdges;
5368
+ __exportStar(require_audit(), exports);
5369
+ __exportStar(require_conversation_provenance(), exports);
5370
+ exports.ACTION_PROVENANCE_LABELS = /* @__PURE__ */ new Set([
5371
+ "Person",
5372
+ "UserProfile",
5373
+ "AdminUser",
5374
+ "Organization",
5375
+ "LocalBusiness",
5376
+ "CloudflareTunnel",
5377
+ "CloudflareHostname"
5378
+ ]);
5379
+ exports.PROVENANCE_SOURCE_LABELS = /* @__PURE__ */ new Set([
5380
+ "Task",
5381
+ "Conversation",
5382
+ "Message"
5383
+ ]);
5384
+ function requiresActionProvenance(labels) {
5385
+ for (const label of labels) {
5386
+ if (exports.ACTION_PROVENANCE_LABELS.has(label))
5387
+ return true;
5388
+ }
5389
+ return false;
5390
+ }
5391
+ exports.VECTOR_INDEXED_LABELS = /* @__PURE__ */ new Set([
5392
+ "Question",
5393
+ "DefinedTerm",
5394
+ "Review",
5395
+ "Service",
5396
+ "Person",
5397
+ "LocalBusiness",
5398
+ "Organization",
5399
+ "PriceSpecification",
5400
+ "Task",
5401
+ "CreativeWork",
5402
+ "DigitalDocument",
5403
+ "KnowledgeDocument",
5404
+ "ConversationArchive",
5405
+ "Section",
5406
+ "Chunk",
5407
+ "Project",
5408
+ "Position",
5409
+ "Conversation",
5410
+ "Message",
5411
+ "Event",
5412
+ "Workflow",
5413
+ "Preference",
5414
+ "Listing",
5415
+ "Idea",
5416
+ "TimelineEvent",
5417
+ "Report",
5418
+ "FileArtifact"
5419
+ ]);
5420
+ exports.DOCUMENT_ARCHIVE_LABELS = /* @__PURE__ */ new Set([
5421
+ "KnowledgeDocument",
5422
+ "DigitalDocument",
5423
+ "ConversationArchive"
5424
+ ]);
5425
+ function labelsAreIndexed(labels) {
5426
+ for (const l of labels)
5427
+ if (exports.VECTOR_INDEXED_LABELS.has(l))
5428
+ return true;
5429
+ return false;
5430
+ }
5431
+ function boundedEmbedText(labels, props) {
5432
+ const PER_VALUE = 2e3;
5433
+ const TOTAL = 8e3;
5434
+ const docPreferred = labels.some((l) => exports.DOCUMENT_ARCHIVE_LABELS.has(l));
5435
+ const parts = [`[${labels.join(", ")}]`];
5436
+ for (const [k, v] of Object.entries(props)) {
5437
+ if (v === null || v === void 0 || k === "embedding")
5438
+ continue;
5439
+ if (docPreferred && (k === "body" || k === "text"))
5440
+ continue;
5441
+ const s = String(v);
5442
+ parts.push(`${k}: ${s.length > PER_VALUE ? s.slice(0, PER_VALUE) : s}`);
5443
+ }
5444
+ const joined = parts.join(" | ");
5445
+ return joined.length > TOTAL ? joined.slice(0, TOTAL) : joined;
5446
+ }
5447
+ function findProvenanceCandidates(relationships) {
5448
+ return relationships.filter((r) => r.type === "PRODUCED" && r.direction === "incoming");
5449
+ }
5450
+ function stampCreatedBy(props, createdBy) {
5451
+ return {
5452
+ ...props,
5453
+ createdByAgent: createdBy.agent ?? "unknown",
5454
+ createdBySession: createdBy.session ?? "unknown",
5455
+ createdByTool: createdBy.tool ?? null,
5456
+ createdBySource: createdBy.source ?? null
5457
+ };
5458
+ }
5459
+ async function writeNodeWithEdges(params) {
5460
+ const { session, labels, props, relationships, createdBy } = params;
5461
+ const agentLabel = createdBy.agent ?? createdBy.source ?? "unknown";
5462
+ const labelCsv = labels.join(",");
5463
+ const isSystemBootstrap = (createdBy.agent ?? "") === "system";
5464
+ if (!isSystemBootstrap) {
5465
+ const accountId = props.accountId;
5466
+ const expectedAccountId = params.expectedAccountId ?? process.env.ACCOUNT_ID;
5467
+ if (typeof accountId !== "string" || !expectedAccountId || accountId !== expectedAccountId) {
5468
+ const slice = typeof accountId === "string" ? accountId.slice(0, 8) : "missing";
5469
+ process.stderr.write(`[graph-write] reject reason=invalid-account-id accountId=${slice} writer=${agentLabel}
5470
+ `);
5471
+ throw new Error(`Write doctrine violated: invalid-account-id (${slice}) \u2014 accountId must equal ACCOUNT_ID set by the spawning process. See .docs/neo4j.md "Account isolation invariant".`);
5472
+ }
5473
+ }
5474
+ const reviewDigestActionTool = typeof props.actionTool === "string" && props.actionTool === "review-digest-compose";
5475
+ if (labels.includes("ReviewAlert") || reviewDigestActionTool) {
5476
+ const actionToolField = reviewDigestActionTool ? "review-digest-compose" : "n/a";
5477
+ process.stderr.write(`[graph-write] reject reason=removed-feature labels=${labelCsv} actionTool=${actionToolField} agent=${agentLabel}
5478
+ `);
5479
+ throw new Error("Write doctrine violated: review-detector feature removed \u2014 `:ReviewAlert` and `:Event {actionTool:'review-digest-compose'}` writes are not allowed.");
5480
+ }
5481
+ if (!relationships || relationships.length < 1) {
5482
+ process.stderr.write(`[graph-write] reject reason=zero-relationships labels=${labelCsv} agent=${agentLabel}
5483
+ `);
5484
+ throw new Error("Write doctrine violated: a node must be created with at least one relationship. See .docs/neo4j.md (Write doctrine).");
5485
+ }
5486
+ const indexed = labelsAreIndexed(labels);
5487
+ let embedded = Array.isArray(props.embedding) && props.embedding.length > 0;
5488
+ const workingProps = { ...props };
5489
+ if (indexed && !embedded && typeof params.embed === "function") {
5490
+ try {
5491
+ const vec = await params.embed(boundedEmbedText(labels, props));
5492
+ if (Array.isArray(vec) && vec.length > 0) {
5493
+ workingProps.embedding = vec;
5494
+ embedded = true;
5495
+ }
5496
+ } catch (err) {
5497
+ process.stderr.write(`[graph-write] warn reason=embed-failed labels=${labelCsv} agent=${agentLabel} detail=${err instanceof Error ? err.message : String(err)}
5498
+ `);
5499
+ }
5500
+ }
5501
+ const labelStr = labels.map((l) => `\`${l.replace(/`/g, "")}\``).join(":");
5502
+ const nodeProps = stampCreatedBy(workingProps, createdBy);
5503
+ return await session.executeWrite(async (tx) => {
5504
+ const targetIds = relationships.map((r) => r.targetNodeId);
5505
+ const check = await tx.run(`UNWIND $ids AS id MATCH (t) WHERE elementId(t) = id RETURN elementId(t) AS id, labels(t) AS labels`, { ids: targetIds });
5506
+ const labelsByTarget = /* @__PURE__ */ new Map();
5507
+ for (const rec of check.records) {
5508
+ labelsByTarget.set(rec.get("id"), rec.get("labels"));
5509
+ }
5510
+ const found = labelsByTarget.size;
5511
+ const uniqueRequested = new Set(targetIds).size;
5512
+ if (found !== uniqueRequested) {
5513
+ process.stderr.write(`[graph-write] reject reason=unresolved-target labels=${labelCsv} agent=${agentLabel} requested=${uniqueRequested} found=${found}
5514
+ `);
5515
+ throw new Error(`Write doctrine violated: ${uniqueRequested - found} of ${uniqueRequested} relationship target(s) did not resolve (elementId mismatch). No node created.`);
5516
+ }
5517
+ let provenanceSourceId = null;
5518
+ let provenanceSourceLabel = null;
5519
+ if (requiresActionProvenance(labels) && (createdBy.agent ?? "") !== "system") {
5520
+ const candidates = findProvenanceCandidates(relationships);
5521
+ const matched = candidates.map((r) => {
5522
+ const lbls = labelsByTarget.get(r.targetNodeId);
5523
+ if (!Array.isArray(lbls))
5524
+ return null;
5525
+ const sourceLabel = lbls.find((l) => exports.PROVENANCE_SOURCE_LABELS.has(l));
5526
+ return sourceLabel ? { rel: r, sourceLabel } : null;
5527
+ }).filter((m) => m !== null);
5528
+ if (matched.length === 0) {
5529
+ process.stderr.write(`[graph-write] warn reason=missing-provenance labels=${labelCsv} agent=${agentLabel}
5530
+ `);
5531
+ } else {
5532
+ provenanceSourceId = matched[0].rel.targetNodeId;
5533
+ provenanceSourceLabel = matched[0].sourceLabel;
5534
+ }
5535
+ }
5536
+ let nodeRes;
5537
+ try {
5538
+ nodeRes = await tx.run(`CREATE (n:${labelStr} $props) RETURN elementId(n) AS nodeId, labels(n) AS nodeLabels`, { props: nodeProps });
5539
+ } catch (err) {
5540
+ const code = err?.code ?? "";
5541
+ if (code === "Neo.ClientError.Schema.ConstraintValidationFailed" && labels.includes("UserProfile")) {
5542
+ const accountIdProp = nodeProps.accountId;
5543
+ const userIdProp = nodeProps.userId;
5544
+ const acctSlice2 = typeof accountIdProp === "string" ? accountIdProp.slice(0, 8) : "unknown";
5545
+ const userSlice = typeof userIdProp === "string" ? userIdProp.slice(0, 8) : "unknown";
5546
+ process.stderr.write(`[graph-write] reject reason=user-profile-uniqueness-violation accountId=${acctSlice2} userId=${userSlice} writer=${agentLabel}
5547
+ `);
5548
+ }
5549
+ throw err;
5550
+ }
5551
+ const nodeId = nodeRes.records[0].get("nodeId");
5552
+ const nodeLabels = nodeRes.records[0].get("nodeLabels");
5553
+ let edgesCreated = 0;
5554
+ for (const rel of relationships) {
5555
+ const type = rel.type.replace(/`/g, "");
5556
+ const q = rel.direction === "outgoing" ? `MATCH (a), (b) WHERE elementId(a) = $from AND elementId(b) = $to CREATE (a)-[:\`${type}\`]->(b)` : `MATCH (a), (b) WHERE elementId(a) = $from AND elementId(b) = $to CREATE (b)-[:\`${type}\`]->(a)`;
5557
+ const r = await tx.run(q, { from: nodeId, to: rel.targetNodeId });
5558
+ const created = r.summary.counters.updates().relationshipsCreated;
5559
+ if (created === 0) {
5560
+ process.stderr.write(`[graph-write] reject reason=unresolved-target-on-create labels=${labelCsv} agent=${agentLabel} relType=${rel.type} targetId=${rel.targetNodeId}
5561
+ `);
5562
+ throw new Error(`Write doctrine violated: relationship CREATE to target ${rel.targetNodeId} produced 0 edges (target likely deleted concurrently after pre-check). Transaction rolled back.`);
5563
+ }
5564
+ edgesCreated += created;
5565
+ }
5566
+ if (edgesCreated !== relationships.length) {
5567
+ process.stderr.write(`[graph-write] reject reason=edge-count-mismatch labels=${labelCsv} agent=${agentLabel} requested=${relationships.length} created=${edgesCreated}
5568
+ `);
5569
+ throw new Error(`Write doctrine violated: expected ${relationships.length} edges, created ${edgesCreated}. Transaction rolled back.`);
5570
+ }
5571
+ process.stderr.write(`[graph-write] accepted labels=${labelCsv} edges=${edgesCreated} createdByAgent=${createdBy.agent ?? "unknown"} createdByTool=${createdBy.tool ?? createdBy.source ?? "unknown"} producedBy=${provenanceSourceLabel ?? "none"}:${provenanceSourceId ?? "none"}
5572
+ `);
5573
+ const acctSlice = typeof props.accountId === "string" ? props.accountId.slice(0, 8) : "none";
5574
+ process.stderr.write(`[graph-write] op=node-written label=${labelCsv} accountId=${acctSlice} embedded=${embedded} indexed=${indexed}
5575
+ `);
5576
+ return { nodeId, labels: nodeLabels, edgesCreated };
5577
+ });
5578
+ }
5579
+ }
5580
+ });
5581
+
5214
5582
  // node_modules/hono/dist/utils/mime.js
5215
5583
  var getMimeType = (filename, mimes = baseMimes) => {
5216
5584
  const regexp = /\.([a-zA-Z0-9]+?)$/;
@@ -9192,12 +9560,25 @@ import { resolve as resolve4, basename } from "path";
9192
9560
  var TAG15 = "[whatsapp:outbound]";
9193
9561
  var WHATSAPP_DOCUMENT_MAX_BYTES = 100 * 1024 * 1024;
9194
9562
  var lastDocumentOutboundAt = /* @__PURE__ */ new Map();
9563
+ var lastRouteDocumentOutboundAt = /* @__PURE__ */ new Map();
9195
9564
  function normalizeJid(to) {
9196
9565
  return to.includes("@") ? to : toWhatsappJid(to);
9197
9566
  }
9567
+ function routeKey(to, filePath) {
9568
+ return `${normalizeJid(to)}\0${filePath}`;
9569
+ }
9198
9570
  function documentOutboundAt(to) {
9199
9571
  return lastDocumentOutboundAt.get(normalizeJid(to));
9200
9572
  }
9573
+ function recordDocumentOutbound(to) {
9574
+ lastDocumentOutboundAt.set(normalizeJid(to), Date.now());
9575
+ }
9576
+ function recordRouteDocumentOutbound(to, filePath) {
9577
+ lastRouteDocumentOutboundAt.set(routeKey(to, filePath), Date.now());
9578
+ }
9579
+ function routeDocumentOutboundAt(to, filePath) {
9580
+ return lastRouteDocumentOutboundAt.get(routeKey(to, filePath));
9581
+ }
9201
9582
  async function sendWhatsAppDocument(input) {
9202
9583
  const { to, filePath, caption, accountId, maxyAccountId, platformRoot: platformRoot2 } = input;
9203
9584
  if (!to || !filePath) {
@@ -9252,7 +9633,7 @@ async function sendWhatsAppDocument(input) {
9252
9633
  `${TAG15} sent document to=${jid} file=${filename} bytes=${fileStat.size} ok=${result.success}` + (result.messageId ? ` id=${result.messageId}` : "")
9253
9634
  );
9254
9635
  if (result.success) {
9255
- lastDocumentOutboundAt.set(jid, Date.now());
9636
+ recordDocumentOutbound(to);
9256
9637
  return { ok: true, messageId: result.messageId };
9257
9638
  }
9258
9639
  return { ok: false, status: 500, error: result.error ?? "send failed" };
@@ -9269,12 +9650,21 @@ function makeWhatsAppFileDelivery(entry) {
9269
9650
  let turnStartedAt = null;
9270
9651
  let failedFiles = [];
9271
9652
  let sendUserFileAttempts = 0;
9653
+ let routeCalls = [];
9272
9654
  return {
9273
9655
  isFileDeliveryTool(toolName) {
9274
9656
  return toolName === SEND_USER_FILE || toolName === WHATSAPP_SEND_DOCUMENT;
9275
9657
  },
9276
9658
  async onFileToolUse(use) {
9277
9659
  if (turnStartedAt === null) turnStartedAt = Date.now();
9660
+ if (use.toolName === WHATSAPP_SEND_DOCUMENT) {
9661
+ const input2 = use.input ?? {};
9662
+ routeCalls.push({
9663
+ to: typeof input2.to === "string" ? input2.to : void 0,
9664
+ filePath: typeof input2.filePath === "string" ? input2.filePath : void 0
9665
+ });
9666
+ return;
9667
+ }
9278
9668
  if (use.toolName !== SEND_USER_FILE) return;
9279
9669
  const input = use.input ?? {};
9280
9670
  const files = Array.isArray(input.files) ? input.files.filter((f) => typeof f === "string") : [];
@@ -9311,9 +9701,11 @@ function makeWhatsAppFileDelivery(entry) {
9311
9701
  const startedAt = turnStartedAt ?? 0;
9312
9702
  const failed = failedFiles;
9313
9703
  const attempts = sendUserFileAttempts;
9704
+ const routes = routeCalls;
9314
9705
  turnStartedAt = null;
9315
9706
  failedFiles = [];
9316
9707
  sendUserFileAttempts = 0;
9708
+ routeCalls = [];
9317
9709
  const sid = entry.sessionId.slice(0, 8);
9318
9710
  for (const file of failed) {
9319
9711
  console.error(
@@ -9322,10 +9714,15 @@ function makeWhatsAppFileDelivery(entry) {
9322
9714
  }
9323
9715
  const okAt = documentOutboundAt(entry.senderId);
9324
9716
  const documentWentOut = okAt !== void 0 && okAt >= startedAt;
9325
- if (firedTools.includes(WHATSAPP_SEND_DOCUMENT) && !documentWentOut) {
9326
- console.error(
9327
- `${TAG16} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${WHATSAPP_SEND_DOCUMENT}`
9328
- );
9717
+ for (const call of routes) {
9718
+ const routeAt = call.to !== void 0 && call.filePath !== void 0 ? routeDocumentOutboundAt(call.to, call.filePath) : void 0;
9719
+ const delivered = routeAt !== void 0 && routeAt >= startedAt;
9720
+ if (!delivered) {
9721
+ const fileField = call.filePath !== void 0 ? ` file=${call.filePath}` : "";
9722
+ console.error(
9723
+ `${TAG16} file-delivery-unreconciled sender=${entry.senderId} sessionId=${sid} tool=${WHATSAPP_SEND_DOCUMENT}${fileField}`
9724
+ );
9725
+ }
9329
9726
  }
9330
9727
  if (firedTools.includes(SEND_USER_FILE) && attempts === 0 && !documentWentOut) {
9331
9728
  console.error(
@@ -10813,6 +11210,7 @@ app3.post("/send-document", async (c) => {
10813
11210
  platformRoot: PLATFORM_ROOT4
10814
11211
  });
10815
11212
  if (!result.ok) return c.json({ error: result.error }, result.status);
11213
+ recordRouteDocumentOutbound(to, filePath);
10816
11214
  return c.json({ success: true, messageId: result.messageId });
10817
11215
  } catch (err) {
10818
11216
  console.error(`${TAG19} send-document error: ${String(err)}`);
@@ -14718,6 +15116,7 @@ function buildScopeAndSliceClause(allowedScopes, sliceToken, alias = "node") {
14718
15116
  params: { allowedScopes }
14719
15117
  };
14720
15118
  }
15119
+ var DEFAULT_VECTOR_THRESHOLD = 0.82;
14721
15120
  function escapeLucene(query) {
14722
15121
  return query.replace(/[+\-&|!(){}[\]^"~*?:\\/]/g, "\\$&");
14723
15122
  }
@@ -15272,7 +15671,6 @@ function plainProperties(properties) {
15272
15671
  // server/routes/admin/graph-search.ts
15273
15672
  var DEFAULT_LIMIT = 20;
15274
15673
  var MAX_LIMIT = 2e3;
15275
- var DEFAULT_VECTOR_THRESHOLD = 0.82;
15276
15674
  var MESSAGE_FAMILY_LABELS = ["Message", "UserMessage", "AssistantMessage", "WhatsAppMessage"];
15277
15675
  var CONVERSATION_PARENT_LABELS = /* @__PURE__ */ new Set(["AdminConversation", "PublicConversation"]);
15278
15676
  var app16 = new Hono();
@@ -15290,8 +15688,10 @@ app16.get("/", requireAdminSession, async (c) => {
15290
15688
  if (!q) return c.json({ error: "q (search query) required" }, 400);
15291
15689
  const labels = rawLabels ? rawLabels.split(",").map((s) => s.trim()).filter((s) => s.length > 0) : [];
15292
15690
  const wildcard = labels.includes("*");
15293
- if (labels.length === 0) {
15294
- return c.json({ error: "Select at least one filter chip before searching." }, 400);
15691
+ const noChips = labels.length === 0;
15692
+ const allLabels = wildcard || noChips;
15693
+ if (noChips && !wildcard) {
15694
+ console.error(`[graph-search] op=labels-default applied=all query="${q}"`);
15295
15695
  }
15296
15696
  const parsedLimit = rawLimit ? parseInt(rawLimit, 10) : DEFAULT_LIMIT;
15297
15697
  const limit = Number.isFinite(parsedLimit) && parsedLimit > 0 ? Math.min(parsedLimit, MAX_LIMIT) : DEFAULT_LIMIT;
@@ -15302,8 +15702,8 @@ app16.get("/", requireAdminSession, async (c) => {
15302
15702
  vectorThreshold = parsed;
15303
15703
  }
15304
15704
  }
15305
- const wantsBodyFulltext = !wildcard && labels.some((l) => CONVERSATION_PARENT_LABELS.has(l));
15306
- const forwardedLabels = wildcard ? void 0 : wantsBodyFulltext ? Array.from(/* @__PURE__ */ new Set([...labels, ...MESSAGE_FAMILY_LABELS])) : labels;
15705
+ const wantsBodyFulltext = !allLabels && labels.some((l) => CONVERSATION_PARENT_LABELS.has(l));
15706
+ const forwardedLabels = allLabels ? void 0 : wantsBodyFulltext ? Array.from(/* @__PURE__ */ new Set([...labels, ...MESSAGE_FAMILY_LABELS])) : labels;
15307
15707
  if (labels.includes("FileArtifact")) {
15308
15708
  await reconcileFileIndexDebounced(accountId);
15309
15709
  }
@@ -15378,7 +15778,7 @@ app16.get("/", requireAdminSession, async (c) => {
15378
15778
  `[graph-search] body-fulltext query="${q}" hits=${bodyFulltextCount} ms=${total}`
15379
15779
  );
15380
15780
  }
15381
- const labelsToken = wildcard ? "*" : labels.join(",");
15781
+ const labelsToken = wildcard ? "*" : noChips ? "all" : labels.join(",");
15382
15782
  const expandedFlag = !wildcard && wantsBodyFulltext ? 1 : 0;
15383
15783
  console.error(
15384
15784
  `[graph-search] query="${q}" labels=${labelsToken} expanded=${expandedFlag} limit=${limit} mode=${res.mode} raw-results=${res.results.length} resolved-results=${resolvedResults.length} expand-ms=${res.expandMs} total-ms=${total}`
@@ -19248,7 +19648,15 @@ app42.post("/", async (c) => {
19248
19648
  var session_default2 = app42;
19249
19649
 
19250
19650
  // app/lib/graph-health.ts
19651
+ var import_dist5 = __toESM(require_dist4(), 1);
19251
19652
  var HOUR_MS = 60 * 60 * 1e3;
19653
+ function renderLabelTop(rows) {
19654
+ return rows.map((b) => {
19655
+ const labels = b.labels.join("+") || "(none)";
19656
+ const c = typeof b.count === "number" ? b.count : b.count.toNumber?.() ?? 0;
19657
+ return `${labels}:${c}`;
19658
+ }).join(",");
19659
+ }
19252
19660
  var timer = null;
19253
19661
  async function runGraphHealthTick() {
19254
19662
  const session = getSession();
@@ -19285,6 +19693,34 @@ async function runGraphHealthTick() {
19285
19693
  console.error(
19286
19694
  `[graph-health] userprofile-multi accounts=${upAccounts} top=${upTop.length > 0 ? upTop.join(",") : "none"}`
19287
19695
  );
19696
+ const indexed = [...import_dist5.VECTOR_INDEXED_LABELS];
19697
+ const embCount = await session.run(
19698
+ `MATCH (n) WHERE n.embedding IS NULL AND any(l IN labels(n) WHERE l IN $indexed)
19699
+ RETURN count(n) AS total`,
19700
+ { indexed }
19701
+ );
19702
+ const embTotal = embCount.records[0]?.get("total")?.toNumber?.() ?? 0;
19703
+ const embTopRes = await session.run(
19704
+ `MATCH (n) WHERE n.embedding IS NULL AND any(l IN labels(n) WHERE l IN $indexed)
19705
+ WITH labels(n) AS lbls, count(*) AS c
19706
+ ORDER BY c DESC LIMIT 5
19707
+ RETURN collect({labels: lbls, count: c}) AS top`,
19708
+ { indexed }
19709
+ );
19710
+ const embTop = embTopRes.records[0]?.get("top") ?? [];
19711
+ console.error(`[embed-audit] null-embedding labels=${renderLabelTop(embTop) || "none"} count=${embTotal}`);
19712
+ const acctCount = await session.run(
19713
+ `MATCH (n) WHERE n.accountId IS NULL RETURN count(n) AS total`
19714
+ );
19715
+ const acctTotal = acctCount.records[0]?.get("total")?.toNumber?.() ?? 0;
19716
+ const acctTopRes = await session.run(
19717
+ `MATCH (n) WHERE n.accountId IS NULL
19718
+ WITH labels(n) AS lbls, count(*) AS c
19719
+ ORDER BY c DESC LIMIT 5
19720
+ RETURN collect({labels: lbls, count: c}) AS top`
19721
+ );
19722
+ const acctTop = acctTopRes.records[0]?.get("top") ?? [];
19723
+ console.error(`[account-audit] null-account labels=${renderLabelTop(acctTop) || "none"} count=${acctTotal}`);
19288
19724
  } catch (err) {
19289
19725
  console.error(
19290
19726
  `[graph-health] query failed: ${err instanceof Error ? err.message : String(err)}`
@@ -19436,15 +19872,29 @@ var TAG30 = "[whatsapp-adaptor]";
19436
19872
  function whatsappTurnTimeoutMs() {
19437
19873
  return Number(process.env.WHATSAPP_PTY_TURN_TIMEOUT_MS ?? String(5 * 6e4));
19438
19874
  }
19875
+ function composeTurn(input) {
19876
+ const caption = input.text.trim();
19877
+ const hasFileMedia = !!input.mediaPath && input.mediaType !== "audio";
19878
+ if (!hasFileMedia) return caption;
19879
+ const type = input.mediaType ?? "file";
19880
+ const note = input.role === "admin" ? `[Inbound WhatsApp ${type}: ${input.mediaPath}${input.mediaMimetype ? ` (${input.mediaMimetype})` : ""}. Read this file to see what the sender shared.]` : `[The sender shared a ${type}. You cannot open shared files in this session \u2014 ask them to describe or paste the relevant content.]`;
19881
+ return caption ? `${caption}
19882
+
19883
+ ${note}` : note;
19884
+ }
19439
19885
  async function dispatchToClaude(input) {
19440
- if (!input.text.trim()) return;
19886
+ const hasFileMedia = !!input.mediaPath && input.mediaType !== "audio";
19887
+ const mediaField = hasFileMedia ? `media=${input.mediaType} mediaPath=${input.mediaPath}` : input.mediaType === "audio" ? "media=audio mediaPath=transcribed" : "media=none";
19888
+ console.error(`${TAG30} inbound-media ${mediaField} role=${input.role} senderId=${input.senderId}`);
19889
+ const text = composeTurn(input);
19890
+ if (!text.trim()) return;
19441
19891
  const result = await dispatchOnce({
19442
19892
  accountId: input.accountId,
19443
19893
  senderId: input.senderId,
19444
19894
  role: input.role,
19445
19895
  channel: "whatsapp",
19446
19896
  agentSlug: input.agentSlug,
19447
- text: input.text,
19897
+ text,
19448
19898
  timeoutMs: whatsappTurnTimeoutMs()
19449
19899
  });
19450
19900
  if ("error" in result) {
@@ -20237,10 +20687,7 @@ var brandedHtmlCache = /* @__PURE__ */ new Map();
20237
20687
  function loadBrandingCache(agentSlug) {
20238
20688
  const configDir2 = join17(homedir2(), BRAND.configDir);
20239
20689
  try {
20240
- const accountJsonPath = join17(configDir2, "account.json");
20241
- if (!existsSync23(accountJsonPath)) return null;
20242
- const account = JSON.parse(readFileSync22(accountJsonPath, "utf-8"));
20243
- const accountId = account.accountId;
20690
+ const accountId = getDefaultAccountId();
20244
20691
  if (!accountId) return null;
20245
20692
  const cachePath = join17(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
20246
20693
  if (!existsSync23(cachePath)) return null;
@@ -20250,15 +20697,9 @@ function loadBrandingCache(agentSlug) {
20250
20697
  }
20251
20698
  }
20252
20699
  function resolveDefaultSlug() {
20253
- try {
20254
- const configDir2 = join17(homedir2(), BRAND.configDir);
20255
- const accountJsonPath = join17(configDir2, "account.json");
20256
- if (!existsSync23(accountJsonPath)) return null;
20257
- const account = JSON.parse(readFileSync22(accountJsonPath, "utf-8"));
20258
- return account.defaultAgent || null;
20259
- } catch {
20260
- return null;
20261
- }
20700
+ const account = resolveAccount();
20701
+ if (!account) return null;
20702
+ return resolveDefaultAgentSlug(account.accountDir);
20262
20703
  }
20263
20704
  function brandedPublicHtml(agentSlug) {
20264
20705
  const baseHtml = cachedHtml("public.html");
@@ -20304,6 +20745,7 @@ app43.get("/", (c) => {
20304
20745
  503
20305
20746
  );
20306
20747
  }
20748
+ console.error(`[public-root] op=serve-default slug=${defaultSlug}`);
20307
20749
  return c.html(brandedPublicHtml(defaultSlug));
20308
20750
  }
20309
20751
  return c.html(cachedHtml("index.html"));
@@ -20584,7 +21026,7 @@ init({
20584
21026
  platformRoot: resolve26(process.env.MAXY_PLATFORM_ROOT ?? join17(__dirname, "..")),
20585
21027
  accountConfig: bootAccountConfig,
20586
21028
  onMessage: async (msg) => {
20587
- if (msg.text && !msg.isOwnerMirror) {
21029
+ if ((msg.text || msg.mediaPath) && !msg.isOwnerMirror) {
20588
21030
  try {
20589
21031
  void msg.composing().catch(() => {
20590
21032
  });
@@ -20606,6 +21048,9 @@ init({
20606
21048
  role: msg.agentType,
20607
21049
  agentSlug: agentSlugForBridge,
20608
21050
  text: msg.text,
21051
+ mediaPath: msg.mediaPath,
21052
+ mediaType: msg.mediaType,
21053
+ mediaMimetype: msg.mediaMimetype,
20609
21054
  reply: msg.reply
20610
21055
  });
20611
21056
  } catch (err) {