@rubytech/create-maxy 1.0.499 → 1.0.501

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 (109) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/templates/agents/admin/IDENTITY.md +1 -1
  3. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/PLUGIN.md +36 -8
  4. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/index.js +229 -153
  5. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/index.js.map +1 -1
  6. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/loop-api.d.ts +19 -1
  7. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/loop-api.d.ts.map +1 -1
  8. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/loop-api.js +99 -3
  9. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/loop-api.js.map +1 -1
  10. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/customer-preferences.d.ts +10 -0
  11. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/customer-preferences.d.ts.map +1 -0
  12. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/customer-preferences.js +24 -0
  13. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/customer-preferences.js.map +1 -0
  14. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/feedback.d.ts +16 -0
  15. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/feedback.d.ts.map +1 -0
  16. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/feedback.js +35 -0
  17. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/feedback.js.map +1 -0
  18. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/key-register.js +1 -1
  19. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/key-register.js.map +1 -1
  20. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-enquiry.d.ts +13 -0
  21. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-enquiry.d.ts.map +1 -0
  22. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-enquiry.js +41 -0
  23. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-enquiry.js.map +1 -0
  24. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-batch.d.ts +9 -0
  25. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-batch.d.ts.map +1 -0
  26. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-batch.js +16 -0
  27. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-batch.js.map +1 -0
  28. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-request.d.ts +15 -0
  29. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-request.d.ts.map +1 -0
  30. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-request.js +11 -0
  31. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-request.js.map +1 -0
  32. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match.d.ts +10 -0
  33. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match.d.ts.map +1 -0
  34. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match.js +39 -0
  35. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match.js.map +1 -0
  36. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-detail.d.ts +9 -0
  37. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-detail.d.ts.map +1 -0
  38. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-detail.js +33 -0
  39. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-detail.js.map +1 -0
  40. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-search.d.ts +18 -0
  41. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-search.d.ts.map +1 -0
  42. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-search.js +59 -0
  43. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-search.js.map +1 -0
  44. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-detail.d.ts +10 -0
  45. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-detail.d.ts.map +1 -0
  46. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-detail.js +39 -0
  47. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-detail.js.map +1 -0
  48. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-listed.d.ts +12 -0
  49. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-listed.d.ts.map +1 -0
  50. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-listed.js +28 -0
  51. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-listed.js.map +1 -0
  52. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-request.d.ts +15 -0
  53. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-request.d.ts.map +1 -0
  54. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-request.js +11 -0
  55. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-request.js.map +1 -0
  56. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-search.d.ts +16 -0
  57. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-search.d.ts.map +1 -0
  58. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-search.js +39 -0
  59. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-search.js.map +1 -0
  60. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/supplier.d.ts +13 -0
  61. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/supplier.d.ts.map +1 -0
  62. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/supplier.js +49 -0
  63. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/supplier.js.map +1 -0
  64. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/team-availability.d.ts +7 -0
  65. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/team-availability.d.ts.map +1 -0
  66. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/team-availability.js +15 -0
  67. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/team-availability.js.map +1 -0
  68. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-create.d.ts +14 -0
  69. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-create.d.ts.map +1 -0
  70. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-create.js +11 -0
  71. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-create.js.map +1 -0
  72. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-detail.d.ts +9 -0
  73. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-detail.d.ts.map +1 -0
  74. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-detail.js +40 -0
  75. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-detail.js.map +1 -0
  76. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-search.d.ts +13 -0
  77. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-search.d.ts.map +1 -0
  78. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-search.js +34 -0
  79. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-search.js.map +1 -0
  80. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-update.d.ts +14 -0
  81. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-update.d.ts.map +1 -0
  82. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-update.js +18 -0
  83. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-update.js.map +1 -0
  84. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/index.ts +335 -158
  85. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/lib/loop-api.ts +140 -3
  86. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/customer-preferences.ts +60 -0
  87. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/feedback.ts +80 -0
  88. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/key-register.ts +1 -1
  89. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/marketing-enquiry.ts +105 -0
  90. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/marketing-match-batch.ts +48 -0
  91. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/marketing-match-request.ts +37 -0
  92. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/marketing-match.ts +78 -0
  93. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/people-detail.ts +63 -0
  94. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/people-search.ts +93 -0
  95. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/property-detail.ts +70 -0
  96. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/property-listed.ts +67 -0
  97. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/property-request.ts +37 -0
  98. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/property-search.ts +80 -0
  99. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/supplier.ts +120 -0
  100. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/team-availability.ts +42 -0
  101. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/viewing-create.ts +36 -0
  102. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/viewing-detail.ts +70 -0
  103. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/viewing-search.ts +74 -0
  104. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/viewing-update.ts +48 -0
  105. package/payload/server/server.js +95 -5
  106. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/feedback-list.ts +0 -54
  107. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/people-list.ts +0 -52
  108. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/properties-list.ts +0 -52
  109. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/src/tools/viewings-list.ts +0 -62
@@ -0,0 +1,48 @@
1
+ import { loopPost, withTeamKey } from "../lib/loop-api.js";
2
+
3
+ type Department = "sales" | "lettings";
4
+
5
+ // Feedback parties map to swagger endpoints:
6
+ // sales: buyer-feedback, seller-feedback
7
+ // lettings: renter-feedback, landlord-feedback
8
+ type FeedbackParty = "buyer" | "seller" | "renter" | "landlord";
9
+ type Action = "note" | "feedback";
10
+
11
+ interface LoopBooleanResponse {
12
+ success?: boolean;
13
+ [key: string]: unknown;
14
+ }
15
+
16
+ export async function viewingUpdate(params: {
17
+ accountId: string;
18
+ teamName: string;
19
+ viewingId: number;
20
+ department: Department;
21
+ action: Action;
22
+ text: string;
23
+ feedbackParty?: FeedbackParty;
24
+ }): Promise<string> {
25
+ const { accountId, teamName, viewingId, department, action, text, feedbackParty } = params;
26
+
27
+ if (action === "feedback" && !feedbackParty) {
28
+ throw new Error("feedbackParty is required when action is 'feedback'. Use: buyer, seller, renter, or landlord.");
29
+ }
30
+
31
+ await withTeamKey<LoopBooleanResponse>(
32
+ accountId,
33
+ teamName,
34
+ "viewings",
35
+ "loop-viewing-update",
36
+ async (apiKey) => {
37
+ const suffix = action === "note"
38
+ ? "note"
39
+ : `${feedbackParty}-feedback`;
40
+ const path = `/residential/${department}/viewings/${viewingId}/${suffix}`;
41
+ // Loop expects the text as a StringResponse body
42
+ return loopPost<LoopBooleanResponse>(apiKey, path, { result: text }, "loop-viewing-update", teamName);
43
+ }
44
+ );
45
+
46
+ const actionLabel = action === "note" ? "Note added" : `${feedbackParty} feedback recorded`;
47
+ return `${actionLabel} for viewing ${viewingId} (${department}) via team "${teamName}".`;
48
+ }
@@ -3258,8 +3258,8 @@ async function GET() {
3258
3258
  // app/lib/claude-agent.ts
3259
3259
  import Anthropic from "@anthropic-ai/sdk";
3260
3260
  import { spawn as spawn2 } from "child_process";
3261
- import { resolve as resolve5 } from "path";
3262
- import { readFileSync as readFileSync5, readdirSync, existsSync as existsSync6, mkdirSync as mkdirSync3, createWriteStream, statSync as statSync2, unlinkSync } from "fs";
3261
+ import { resolve as resolve5, join as join4 } from "path";
3262
+ import { readFileSync as readFileSync5, readdirSync, existsSync as existsSync6, mkdirSync as mkdirSync3, createWriteStream, statSync as statSync2, unlinkSync, cpSync } from "fs";
3263
3263
 
3264
3264
  // app/lib/vnc.ts
3265
3265
  import { spawnSync, execFileSync } from "child_process";
@@ -4703,6 +4703,90 @@ function parsePluginFrontmatter(pluginDir) {
4703
4703
  platform
4704
4704
  };
4705
4705
  }
4706
+ function autoDeliverPremiumPlugins(purchasedPlugins) {
4707
+ if (!purchasedPlugins || purchasedPlugins.length === 0) return;
4708
+ const TAG14 = "[premium-auto-deliver]";
4709
+ const stagingRoot = resolve5(PLATFORM_ROOT4, "../premium-plugins");
4710
+ const pluginsDir = resolve5(PLATFORM_ROOT4, "plugins");
4711
+ if (!existsSync6(stagingRoot)) {
4712
+ console.log(`${TAG14} no staging directory \u2014 skipping`);
4713
+ return;
4714
+ }
4715
+ for (const pluginName of purchasedPlugins) {
4716
+ const stagingDir = resolve5(stagingRoot, pluginName);
4717
+ if (!existsSync6(stagingDir)) {
4718
+ console.log(`${TAG14} ${pluginName}: not in staging \u2014 skipping`);
4719
+ continue;
4720
+ }
4721
+ const bundlePath = join4(stagingDir, "BUNDLE.md");
4722
+ const isBundle = existsSync6(bundlePath);
4723
+ if (isBundle) {
4724
+ let bundleRaw;
4725
+ try {
4726
+ bundleRaw = readFileSync5(bundlePath, "utf-8");
4727
+ } catch (err) {
4728
+ console.log(`${TAG14} ${pluginName}: cannot read BUNDLE.md \u2014 ${err instanceof Error ? err.message : String(err)}`);
4729
+ continue;
4730
+ }
4731
+ const fmMatch = bundleRaw.match(/^---\n([\s\S]*?)\n---/);
4732
+ const subPlugins = [];
4733
+ if (fmMatch) {
4734
+ let inPlugins = false;
4735
+ for (const line of fmMatch[1].split("\n")) {
4736
+ if (/^plugins:/.test(line)) {
4737
+ inPlugins = true;
4738
+ continue;
4739
+ }
4740
+ if (inPlugins) {
4741
+ const m = line.match(/^\s+- (.+)/);
4742
+ if (m) {
4743
+ subPlugins.push(m[1].trim());
4744
+ } else {
4745
+ break;
4746
+ }
4747
+ }
4748
+ }
4749
+ }
4750
+ if (subPlugins.length === 0) {
4751
+ console.log(`${TAG14} ${pluginName}: BUNDLE.md has no plugins list \u2014 skipping`);
4752
+ continue;
4753
+ }
4754
+ let delivered = 0;
4755
+ let skipped = 0;
4756
+ for (const sub of subPlugins) {
4757
+ const target = resolve5(pluginsDir, sub);
4758
+ if (existsSync6(resolve5(target, "PLUGIN.md"))) {
4759
+ skipped++;
4760
+ continue;
4761
+ }
4762
+ const source = resolve5(stagingDir, "plugins", sub);
4763
+ if (!existsSync6(source)) {
4764
+ console.log(`${TAG14} ${pluginName}/${sub}: source missing in staging \u2014 skipping`);
4765
+ continue;
4766
+ }
4767
+ try {
4768
+ cpSync(source, target, { recursive: true });
4769
+ delivered++;
4770
+ } catch (err) {
4771
+ console.log(`${TAG14} ${pluginName}/${sub}: copy failed \u2014 ${err instanceof Error ? err.message : String(err)}`);
4772
+ }
4773
+ }
4774
+ console.log(`${TAG14} ${pluginName} (bundle): ${delivered} delivered, ${skipped} already present`);
4775
+ } else {
4776
+ const target = resolve5(pluginsDir, pluginName);
4777
+ if (existsSync6(resolve5(target, "PLUGIN.md"))) {
4778
+ console.log(`${TAG14} ${pluginName}: already present \u2014 skipping`);
4779
+ continue;
4780
+ }
4781
+ try {
4782
+ cpSync(stagingDir, target, { recursive: true });
4783
+ console.log(`${TAG14} ${pluginName} (standalone): delivered`);
4784
+ } catch (err) {
4785
+ console.log(`${TAG14} ${pluginName}: copy failed \u2014 ${err instanceof Error ? err.message : String(err)}`);
4786
+ }
4787
+ }
4788
+ }
4789
+ }
4706
4790
  function assemblePublicPluginContent(pluginDir) {
4707
4791
  const pluginRoot = resolve5(PLATFORM_ROOT4, "plugins", pluginDir);
4708
4792
  const pluginPath = resolve5(pluginRoot, "PLUGIN.md");
@@ -5231,6 +5315,9 @@ function getUserIdForSession(sessionKey) {
5231
5315
  function getUserNameForSession(sessionKey) {
5232
5316
  return sessionStore.get(sessionKey)?.userName;
5233
5317
  }
5318
+ function getConversationIdForSession(sessionKey) {
5319
+ return sessionStore.get(sessionKey)?.conversationId;
5320
+ }
5234
5321
  function registerGrantSession(sessionKey, accountId, agentName, opts) {
5235
5322
  sessionStore.set(sessionKey, {
5236
5323
  createdAt: Date.now(),
@@ -7457,6 +7544,9 @@ ${soul}` : identityPrompt;
7457
7544
  ${isoTimestamp}
7458
7545
  ${humanReadable} (${effectiveTimezone})
7459
7546
  </datetime>`;
7547
+ if (agentType === "admin") {
7548
+ autoDeliverPremiumPlugins(account.config.purchasedPlugins);
7549
+ }
7460
7550
  if (agentType === "admin") {
7461
7551
  if (sessionUserId) {
7462
7552
  baseSystemPrompt += `
@@ -8021,7 +8111,7 @@ async function POST2(req) {
8021
8111
  );
8022
8112
  }
8023
8113
  const sseLog = agentLogStream("sse-events", account.accountDir);
8024
- const sk = session_key.slice(0, 8);
8114
+ const sk = getConversationIdForSession(session_key)?.slice(0, 8) ?? session_key.slice(0, 8);
8025
8115
  const agentName = getAgentNameForSession(session_key);
8026
8116
  if (!agentName) {
8027
8117
  console.log(`[chat] no agent for session=${sk} \u2014 session expired or server restarted`);
@@ -26356,7 +26446,7 @@ async function createAdminSession(accountId, thinkingView, userId, userName) {
26356
26446
  console.log(`[managed-resume] ${(/* @__PURE__ */ new Date()).toISOString()} conversationId=${conversationId.slice(0, 8)}\u2026 loaded=${loadedMessages} messages (${estimatedTokens} estimated tokens)`);
26357
26447
  }
26358
26448
  }
26359
- console.log(`[session] ${(/* @__PURE__ */ new Date()).toISOString()} admin session created: userId=${userId ?? "\u2013"} userName=${userName ?? "\u2013"} accountId=${accountId} conversationId=${conversationId?.slice(0, 8) ?? "\u2013"}`);
26449
+ console.log(`[session] ${(/* @__PURE__ */ new Date()).toISOString()} admin session created: userId=${userId ?? "\u2013"} userName=${userName ?? "\u2013"} accountId=${accountId} conversationId=${conversationId?.slice(0, 8) ?? "\u2013"} sessionKey=${sessionKey.slice(0, 8)}`);
26360
26450
  return Response.json({
26361
26451
  session_key: sessionKey,
26362
26452
  agent_id: "admin",
@@ -26546,7 +26636,7 @@ async function POST20(req) {
26546
26636
  }
26547
26637
  const encoder = new TextEncoder();
26548
26638
  const sseLog = agentLogStream("sse-events", account.accountDir);
26549
- const sk = session_key.slice(0, 8);
26639
+ const sk = getConversationIdForSession(session_key)?.slice(0, 8) ?? session_key.slice(0, 8);
26550
26640
  const readable = new ReadableStream({
26551
26641
  async start(controller) {
26552
26642
  try {
@@ -1,54 +0,0 @@
1
- import {
2
- aggregateAcrossTeams,
3
- formatAggregationResult,
4
- loopGet,
5
- } from "../lib/loop-api.js";
6
-
7
- interface LoopFeedback {
8
- id?: string;
9
- propertyAddress?: string;
10
- viewingDate?: string;
11
- feedback?: string;
12
- rating?: number;
13
- attendeeName?: string;
14
- status?: string;
15
- [key: string]: unknown;
16
- }
17
-
18
- export async function feedbackList(params: {
19
- accountId: string;
20
- teamName?: string;
21
- limit?: number;
22
- }): Promise<string> {
23
- const { accountId, teamName, limit } = params;
24
-
25
- const result = await aggregateAcrossTeams<LoopFeedback>(
26
- accountId,
27
- "feedback",
28
- "loop-feedback-list",
29
- async (apiKey, team) => {
30
- const data = await loopGet<LoopFeedback[]>(
31
- apiKey,
32
- "/feedback",
33
- "loop-feedback-list",
34
- team
35
- );
36
- return Array.isArray(data) ? data : [];
37
- },
38
- { teamName, limitPerTeam: limit ?? 50, limitTotal: limit ?? 200 }
39
- );
40
-
41
- return formatAggregationResult(
42
- result,
43
- (f) => {
44
- const addr = f.propertyAddress ?? "Unknown property";
45
- const date = f.viewingDate ?? "";
46
- const attendee = f.attendeeName ? ` (${f.attendeeName})` : "";
47
- const rating = f.rating != null ? ` ★${f.rating}` : "";
48
- const text = f.feedback ? `: "${f.feedback}"` : "";
49
- const status = f.status ? ` [${f.status}]` : "";
50
- return `- ${addr} ${date}${attendee}${rating}${status}${text}`;
51
- },
52
- "feedback"
53
- );
54
- }
@@ -1,52 +0,0 @@
1
- import {
2
- aggregateAcrossTeams,
3
- formatAggregationResult,
4
- loopGet,
5
- } from "../lib/loop-api.js";
6
-
7
- interface LoopPerson {
8
- id?: string;
9
- firstName?: string;
10
- lastName?: string;
11
- email?: string;
12
- phone?: string;
13
- type?: string;
14
- [key: string]: unknown;
15
- }
16
-
17
- export async function peopleList(params: {
18
- accountId: string;
19
- search?: string;
20
- teamName?: string;
21
- limit?: number;
22
- }): Promise<string> {
23
- const { accountId, search, teamName, limit } = params;
24
-
25
- const result = await aggregateAcrossTeams<LoopPerson>(
26
- accountId,
27
- "people",
28
- "loop-people-list",
29
- async (apiKey, team) => {
30
- const searchParam = search ? `?search=${encodeURIComponent(search)}` : "";
31
- const data = await loopGet<LoopPerson[]>(
32
- apiKey,
33
- `/people${searchParam}`,
34
- "loop-people-list",
35
- team
36
- );
37
- return Array.isArray(data) ? data : [];
38
- },
39
- { teamName, limitPerTeam: limit ?? 50, limitTotal: limit ?? 200 }
40
- );
41
-
42
- return formatAggregationResult(
43
- result,
44
- (p) => {
45
- const name = [p.firstName, p.lastName].filter(Boolean).join(" ") || "Unknown";
46
- const contact = p.email ?? p.phone ?? "";
47
- const type = p.type ? ` (${p.type})` : "";
48
- return `- ${name}${contact ? ` <${contact}>` : ""}${type}`;
49
- },
50
- "people"
51
- );
52
- }
@@ -1,52 +0,0 @@
1
- import {
2
- aggregateAcrossTeams,
3
- formatAggregationResult,
4
- loopGet,
5
- } from "../lib/loop-api.js";
6
-
7
- interface LoopProperty {
8
- id?: string;
9
- address?: string;
10
- price?: number;
11
- status?: string;
12
- type?: string;
13
- bedrooms?: number;
14
- bathrooms?: number;
15
- description?: string;
16
- [key: string]: unknown;
17
- }
18
-
19
- export async function propertiesList(params: {
20
- accountId: string;
21
- type?: string;
22
- teamName?: string;
23
- limit?: number;
24
- }): Promise<string> {
25
- const { accountId, type, teamName, limit } = params;
26
-
27
- const result = await aggregateAcrossTeams<LoopProperty>(
28
- accountId,
29
- "properties",
30
- "loop-properties-list",
31
- async (apiKey, team) => {
32
- const path = type && type !== "both"
33
- ? `/properties?type=${encodeURIComponent(type)}`
34
- : "/properties";
35
- const data = await loopGet<LoopProperty[]>(apiKey, path, "loop-properties-list", team);
36
- return Array.isArray(data) ? data : [];
37
- },
38
- { teamName, limitPerTeam: limit ?? 50, limitTotal: limit ?? 200 }
39
- );
40
-
41
- return formatAggregationResult(
42
- result,
43
- (p) => {
44
- const price = p.price ? ` — £${p.price.toLocaleString("en-GB")}` : "";
45
- const beds = p.bedrooms ? ` ${p.bedrooms}bed` : "";
46
- const status = p.status ? ` [${p.status}]` : "";
47
- const propType = p.type ? ` (${p.type})` : "";
48
- return `- ${p.address ?? "Unknown address"}${price}${beds}${propType}${status}`;
49
- },
50
- "properties"
51
- );
52
- }
@@ -1,62 +0,0 @@
1
- import {
2
- aggregateAcrossTeams,
3
- formatAggregationResult,
4
- loopGet,
5
- } from "../lib/loop-api.js";
6
-
7
- interface LoopViewing {
8
- id?: string;
9
- propertyAddress?: string;
10
- date?: string;
11
- time?: string;
12
- status?: string;
13
- type?: string;
14
- attendeeName?: string;
15
- [key: string]: unknown;
16
- }
17
-
18
- export async function viewingsList(params: {
19
- accountId: string;
20
- type?: string;
21
- teamName?: string;
22
- dateFrom?: string;
23
- dateTo?: string;
24
- limit?: number;
25
- }): Promise<string> {
26
- const { accountId, type, teamName, dateFrom, dateTo, limit } = params;
27
-
28
- const result = await aggregateAcrossTeams<LoopViewing>(
29
- accountId,
30
- "viewings",
31
- "loop-viewings-list",
32
- async (apiKey, team) => {
33
- const queryParts: string[] = [];
34
- if (type && type !== "both") queryParts.push(`type=${encodeURIComponent(type)}`);
35
- if (dateFrom) queryParts.push(`dateFrom=${encodeURIComponent(dateFrom)}`);
36
- if (dateTo) queryParts.push(`dateTo=${encodeURIComponent(dateTo)}`);
37
- const query = queryParts.length > 0 ? `?${queryParts.join("&")}` : "";
38
-
39
- const data = await loopGet<LoopViewing[]>(
40
- apiKey,
41
- `/viewings${query}`,
42
- "loop-viewings-list",
43
- team
44
- );
45
- return Array.isArray(data) ? data : [];
46
- },
47
- { teamName, limitPerTeam: limit ?? 50, limitTotal: limit ?? 200 }
48
- );
49
-
50
- return formatAggregationResult(
51
- result,
52
- (v) => {
53
- const addr = v.propertyAddress ?? "Unknown property";
54
- const when = [v.date, v.time].filter(Boolean).join(" ");
55
- const status = v.status ? ` [${v.status}]` : "";
56
- const attendee = v.attendeeName ? ` — ${v.attendeeName}` : "";
57
- const viewType = v.type ? ` (${v.type})` : "";
58
- return `- ${addr} — ${when || "No date"}${viewType}${attendee}${status}`;
59
- },
60
- "viewings"
61
- );
62
- }