fodda-mcp 1.46.31 → 1.46.97

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 (289) hide show
  1. package/README.md +14 -94
  2. package/dist/agents/fodda-researcher/skills.d.ts +1 -1
  3. package/dist/agents/fodda-researcher/skills.d.ts.map +1 -1
  4. package/dist/agents/fodda-researcher/skills.js +1 -1
  5. package/dist/brandTemplate.d.ts +1 -1
  6. package/dist/brandTemplate.d.ts.map +1 -1
  7. package/dist/brandTemplate.js +162 -74
  8. package/dist/brandTemplate.js.map +1 -1
  9. package/dist/catalogCache.d.ts +29 -1
  10. package/dist/catalogCache.d.ts.map +1 -1
  11. package/dist/catalogCache.js +267 -16
  12. package/dist/catalogCache.js.map +1 -1
  13. package/dist/coverageRelevance.d.ts +97 -2
  14. package/dist/coverageRelevance.d.ts.map +1 -1
  15. package/dist/coverageRelevance.js +959 -164
  16. package/dist/coverageRelevance.js.map +1 -1
  17. package/dist/editorialFill.d.ts +5 -0
  18. package/dist/editorialFill.d.ts.map +1 -1
  19. package/dist/editorialFill.js +1 -1
  20. package/dist/editorialFill.js.map +1 -1
  21. package/dist/enrichment.d.ts +26 -0
  22. package/dist/enrichment.d.ts.map +1 -1
  23. package/dist/enrichment.js +394 -31
  24. package/dist/enrichment.js.map +1 -1
  25. package/dist/errorHandling.d.ts +35 -7
  26. package/dist/errorHandling.d.ts.map +1 -1
  27. package/dist/errorHandling.js +225 -155
  28. package/dist/errorHandling.js.map +1 -1
  29. package/dist/index.d.ts +25 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +351 -143
  32. package/dist/index.js.map +1 -1
  33. package/dist/jobs/jlens_quarterly_sweep.d.ts +62 -0
  34. package/dist/jobs/jlens_quarterly_sweep.d.ts.map +1 -0
  35. package/dist/jobs/jlens_quarterly_sweep.js +160 -0
  36. package/dist/jobs/jlens_quarterly_sweep.js.map +1 -0
  37. package/dist/pricingCache.d.ts.map +1 -1
  38. package/dist/pricingCache.js +41 -1
  39. package/dist/pricingCache.js.map +1 -1
  40. package/dist/queryCache.d.ts.map +1 -1
  41. package/dist/queryCache.js +2 -0
  42. package/dist/queryCache.js.map +1 -1
  43. package/dist/reportBriefing.d.ts +89 -0
  44. package/dist/reportBriefing.d.ts.map +1 -0
  45. package/dist/reportBriefing.js +662 -0
  46. package/dist/reportBriefing.js.map +1 -0
  47. package/dist/searchTemplate.d.ts.map +1 -1
  48. package/dist/searchTemplate.js +65 -53
  49. package/dist/searchTemplate.js.map +1 -1
  50. package/dist/services/graphRouter.d.ts +7 -0
  51. package/dist/services/graphRouter.d.ts.map +1 -0
  52. package/dist/services/graphRouter.js +7 -0
  53. package/dist/services/graphRouter.js.map +1 -0
  54. package/dist/services/notifications.d.ts +49 -0
  55. package/dist/services/notifications.d.ts.map +1 -0
  56. package/dist/services/notifications.js +206 -0
  57. package/dist/services/notifications.js.map +1 -0
  58. package/dist/sessionTracker.d.ts +19 -2
  59. package/dist/sessionTracker.d.ts.map +1 -1
  60. package/dist/sessionTracker.js +69 -16
  61. package/dist/sessionTracker.js.map +1 -1
  62. package/dist/skillClient.d.ts.map +1 -1
  63. package/dist/skillClient.js +11 -6
  64. package/dist/skillClient.js.map +1 -1
  65. package/dist/svgVisuals.d.ts +17 -19
  66. package/dist/svgVisuals.d.ts.map +1 -1
  67. package/dist/svgVisuals.js +189 -233
  68. package/dist/svgVisuals.js.map +1 -1
  69. package/dist/systemPrompt.d.ts +7 -2
  70. package/dist/systemPrompt.d.ts.map +1 -1
  71. package/dist/systemPrompt.js +110 -68
  72. package/dist/systemPrompt.js.map +1 -1
  73. package/dist/telemetry.d.ts.map +1 -1
  74. package/dist/telemetry.js +15 -0
  75. package/dist/telemetry.js.map +1 -1
  76. package/dist/test_adjacent_trends_polymorphic.d.ts +2 -0
  77. package/dist/test_adjacent_trends_polymorphic.d.ts.map +1 -0
  78. package/dist/test_adjacent_trends_polymorphic.js +154 -0
  79. package/dist/test_adjacent_trends_polymorphic.js.map +1 -0
  80. package/dist/test_book_a_call_live.js +18 -5
  81. package/dist/test_book_a_call_live.js.map +1 -1
  82. package/dist/test_byo_mcp_submission_clarity.d.ts +2 -0
  83. package/dist/test_byo_mcp_submission_clarity.d.ts.map +1 -0
  84. package/dist/test_byo_mcp_submission_clarity.js +142 -0
  85. package/dist/test_byo_mcp_submission_clarity.js.map +1 -0
  86. package/dist/test_capabilities_guidance.d.ts +2 -0
  87. package/dist/test_capabilities_guidance.d.ts.map +1 -0
  88. package/dist/test_capabilities_guidance.js +372 -0
  89. package/dist/test_capabilities_guidance.js.map +1 -0
  90. package/dist/test_client_provenance.d.ts +2 -0
  91. package/dist/test_client_provenance.d.ts.map +1 -0
  92. package/dist/test_client_provenance.js +77 -0
  93. package/dist/test_client_provenance.js.map +1 -0
  94. package/dist/test_connection_surface_cleanup.d.ts +2 -0
  95. package/dist/test_connection_surface_cleanup.d.ts.map +1 -0
  96. package/dist/test_connection_surface_cleanup.js +203 -0
  97. package/dist/test_connection_surface_cleanup.js.map +1 -0
  98. package/dist/test_consult_routing.d.ts +2 -0
  99. package/dist/test_consult_routing.d.ts.map +1 -0
  100. package/dist/test_consult_routing.js +86 -0
  101. package/dist/test_consult_routing.js.map +1 -0
  102. package/dist/test_consult_split.d.ts +2 -0
  103. package/dist/test_consult_split.d.ts.map +1 -0
  104. package/dist/test_consult_split.js +30 -0
  105. package/dist/test_consult_split.js.map +1 -0
  106. package/dist/test_coverage_relevance.js +111 -70
  107. package/dist/test_coverage_relevance.js.map +1 -1
  108. package/dist/test_coverage_replay.d.ts +2 -0
  109. package/dist/test_coverage_replay.d.ts.map +1 -0
  110. package/dist/test_coverage_replay.js +170 -0
  111. package/dist/test_coverage_replay.js.map +1 -0
  112. package/dist/test_dcr_and_legacy_deprecation.js +45 -50
  113. package/dist/test_dcr_and_legacy_deprecation.js.map +1 -1
  114. package/dist/test_demand_signal_logging.d.ts +2 -0
  115. package/dist/test_demand_signal_logging.d.ts.map +1 -0
  116. package/dist/test_demand_signal_logging.js +92 -0
  117. package/dist/test_demand_signal_logging.js.map +1 -0
  118. package/dist/test_earnings_activity_scope.d.ts +5 -0
  119. package/dist/test_earnings_activity_scope.d.ts.map +1 -0
  120. package/dist/test_earnings_activity_scope.js +101 -0
  121. package/dist/test_earnings_activity_scope.js.map +1 -0
  122. package/dist/test_earnings_divergence_live.d.ts +5 -0
  123. package/dist/test_earnings_divergence_live.d.ts.map +1 -0
  124. package/dist/test_earnings_divergence_live.js +135 -0
  125. package/dist/test_earnings_divergence_live.js.map +1 -0
  126. package/dist/test_earnings_hygiene_and_binding.d.ts +5 -0
  127. package/dist/test_earnings_hygiene_and_binding.d.ts.map +1 -0
  128. package/dist/test_earnings_hygiene_and_binding.js +104 -0
  129. package/dist/test_earnings_hygiene_and_binding.js.map +1 -0
  130. package/dist/test_exec_quotes_render.d.ts +2 -0
  131. package/dist/test_exec_quotes_render.d.ts.map +1 -0
  132. package/dist/test_exec_quotes_render.js +86 -0
  133. package/dist/test_exec_quotes_render.js.map +1 -0
  134. package/dist/test_expert_intro.d.ts +2 -0
  135. package/dist/test_expert_intro.d.ts.map +1 -0
  136. package/dist/test_expert_intro.js +57 -0
  137. package/dist/test_expert_intro.js.map +1 -0
  138. package/dist/test_expert_layer.d.ts +11 -0
  139. package/dist/test_expert_layer.d.ts.map +1 -0
  140. package/dist/test_expert_layer.js +356 -0
  141. package/dist/test_expert_layer.js.map +1 -0
  142. package/dist/test_gap_alert.js +8 -0
  143. package/dist/test_gap_alert.js.map +1 -1
  144. package/dist/test_grok_offering_surfaces.d.ts +2 -0
  145. package/dist/test_grok_offering_surfaces.d.ts.map +1 -0
  146. package/dist/test_grok_offering_surfaces.js +155 -0
  147. package/dist/test_grok_offering_surfaces.js.map +1 -0
  148. package/dist/test_human_agent_live.d.ts +2 -0
  149. package/dist/test_human_agent_live.d.ts.map +1 -0
  150. package/dist/test_human_agent_live.js +48 -0
  151. package/dist/test_human_agent_live.js.map +1 -0
  152. package/dist/test_identity_gap.d.ts +2 -0
  153. package/dist/test_identity_gap.d.ts.map +1 -0
  154. package/dist/test_identity_gap.js +171 -0
  155. package/dist/test_identity_gap.js.map +1 -0
  156. package/dist/test_intelligence_and_verifier.d.ts +17 -0
  157. package/dist/test_intelligence_and_verifier.d.ts.map +1 -0
  158. package/dist/test_intelligence_and_verifier.js +162 -0
  159. package/dist/test_intelligence_and_verifier.js.map +1 -0
  160. package/dist/test_latency_mcp_brief5.d.ts +12 -0
  161. package/dist/test_latency_mcp_brief5.d.ts.map +1 -0
  162. package/dist/test_latency_mcp_brief5.js +200 -0
  163. package/dist/test_latency_mcp_brief5.js.map +1 -0
  164. package/dist/test_limit_and_credit_card_capture.d.ts +21 -0
  165. package/dist/test_limit_and_credit_card_capture.d.ts.map +1 -0
  166. package/dist/test_limit_and_credit_card_capture.js +216 -0
  167. package/dist/test_limit_and_credit_card_capture.js.map +1 -0
  168. package/dist/test_list_graphs_topics.js +1 -1
  169. package/dist/test_list_graphs_topics.js.map +1 -1
  170. package/dist/test_live_deployed_mcp_search.d.ts +2 -0
  171. package/dist/test_live_deployed_mcp_search.d.ts.map +1 -0
  172. package/dist/test_live_deployed_mcp_search.js +85 -0
  173. package/dist/test_live_deployed_mcp_search.js.map +1 -0
  174. package/dist/test_live_deployed_split.d.ts +2 -0
  175. package/dist/test_live_deployed_split.d.ts.map +1 -0
  176. package/dist/test_live_deployed_split.js +72 -0
  177. package/dist/test_live_deployed_split.js.map +1 -0
  178. package/dist/test_live_endpoint_runner.js +2 -2
  179. package/dist/test_live_endpoint_runner.js.map +1 -1
  180. package/dist/test_live_mcp.js +1 -1
  181. package/dist/test_live_mcp.js.map +1 -1
  182. package/dist/test_live_neil_widget.d.ts +2 -0
  183. package/dist/test_live_neil_widget.d.ts.map +1 -0
  184. package/dist/test_live_neil_widget.js +84 -0
  185. package/dist/test_live_neil_widget.js.map +1 -0
  186. package/dist/test_longpoll_status.d.ts +2 -0
  187. package/dist/test_longpoll_status.d.ts.map +1 -0
  188. package/dist/test_longpoll_status.js +117 -0
  189. package/dist/test_longpoll_status.js.map +1 -0
  190. package/dist/test_mcp_find_expert_and_vocabulary_routing.d.ts +2 -0
  191. package/dist/test_mcp_find_expert_and_vocabulary_routing.d.ts.map +1 -0
  192. package/dist/test_mcp_find_expert_and_vocabulary_routing.js +130 -0
  193. package/dist/test_mcp_find_expert_and_vocabulary_routing.js.map +1 -0
  194. package/dist/test_next_moves.js +644 -279
  195. package/dist/test_next_moves.js.map +1 -1
  196. package/dist/test_next_moves_transcripts.js +122 -40
  197. package/dist/test_next_moves_transcripts.js.map +1 -1
  198. package/dist/test_on_request_caller_identity.d.ts +13 -0
  199. package/dist/test_on_request_caller_identity.d.ts.map +1 -0
  200. package/dist/test_on_request_caller_identity.js +131 -0
  201. package/dist/test_on_request_caller_identity.js.map +1 -0
  202. package/dist/test_on_request_intercept.d.ts +10 -0
  203. package/dist/test_on_request_intercept.d.ts.map +1 -0
  204. package/dist/test_on_request_intercept.js +95 -0
  205. package/dist/test_on_request_intercept.js.map +1 -0
  206. package/dist/test_onboarding_consent_and_errors.d.ts +2 -0
  207. package/dist/test_onboarding_consent_and_errors.d.ts.map +1 -0
  208. package/dist/test_onboarding_consent_and_errors.js +110 -0
  209. package/dist/test_onboarding_consent_and_errors.js.map +1 -0
  210. package/dist/test_onboarding_live_scenarios.d.ts +2 -0
  211. package/dist/test_onboarding_live_scenarios.d.ts.map +1 -0
  212. package/dist/test_onboarding_live_scenarios.js +189 -0
  213. package/dist/test_onboarding_live_scenarios.js.map +1 -0
  214. package/dist/test_referral_live.d.ts +2 -0
  215. package/dist/test_referral_live.d.ts.map +1 -0
  216. package/dist/test_referral_live.js +33 -0
  217. package/dist/test_referral_live.js.map +1 -0
  218. package/dist/test_referral_piers.d.ts +2 -0
  219. package/dist/test_referral_piers.d.ts.map +1 -0
  220. package/dist/test_referral_piers.js +33 -0
  221. package/dist/test_referral_piers.js.map +1 -0
  222. package/dist/test_report_editorial_briefing.d.ts +21 -0
  223. package/dist/test_report_editorial_briefing.d.ts.map +1 -0
  224. package/dist/test_report_editorial_briefing.js +356 -0
  225. package/dist/test_report_editorial_briefing.js.map +1 -0
  226. package/dist/test_search_graph_quality.d.ts +2 -0
  227. package/dist/test_search_graph_quality.d.ts.map +1 -0
  228. package/dist/test_search_graph_quality.js +493 -0
  229. package/dist/test_search_graph_quality.js.map +1 -0
  230. package/dist/test_service_to_service_auth.d.ts +2 -0
  231. package/dist/test_service_to_service_auth.d.ts.map +1 -0
  232. package/dist/test_service_to_service_auth.js +199 -0
  233. package/dist/test_service_to_service_auth.js.map +1 -0
  234. package/dist/test_sources_live.d.ts +2 -0
  235. package/dist/test_sources_live.d.ts.map +1 -0
  236. package/dist/test_sources_live.js +30 -0
  237. package/dist/test_sources_live.js.map +1 -0
  238. package/dist/test_specialist_and_analyst_tiers.d.ts +2 -0
  239. package/dist/test_specialist_and_analyst_tiers.d.ts.map +1 -0
  240. package/dist/test_specialist_and_analyst_tiers.js +155 -0
  241. package/dist/test_specialist_and_analyst_tiers.js.map +1 -0
  242. package/dist/test_v2_2_visual_hardening.d.ts +5 -0
  243. package/dist/test_v2_2_visual_hardening.d.ts.map +1 -0
  244. package/dist/test_v2_2_visual_hardening.js +333 -0
  245. package/dist/test_v2_2_visual_hardening.js.map +1 -0
  246. package/dist/test_verify_deprecate_render_spec.d.ts +2 -0
  247. package/dist/test_verify_deprecate_render_spec.d.ts.map +1 -0
  248. package/dist/test_verify_deprecate_render_spec.js +217 -0
  249. package/dist/test_verify_deprecate_render_spec.js.map +1 -0
  250. package/dist/test_verify_neil_demo.d.ts +2 -0
  251. package/dist/test_verify_neil_demo.d.ts.map +1 -0
  252. package/dist/test_verify_neil_demo.js +149 -0
  253. package/dist/test_verify_neil_demo.js.map +1 -0
  254. package/dist/test_waitable_research_and_grounded_links.d.ts +2 -0
  255. package/dist/test_waitable_research_and_grounded_links.d.ts.map +1 -0
  256. package/dist/test_waitable_research_and_grounded_links.js +129 -0
  257. package/dist/test_waitable_research_and_grounded_links.js.map +1 -0
  258. package/dist/test_widget_guards.d.ts +2 -0
  259. package/dist/test_widget_guards.d.ts.map +1 -0
  260. package/dist/test_widget_guards.js +229 -0
  261. package/dist/test_widget_guards.js.map +1 -0
  262. package/dist/test_zero_retention_alerts.d.ts +14 -0
  263. package/dist/test_zero_retention_alerts.d.ts.map +1 -0
  264. package/dist/test_zero_retention_alerts.js +76 -0
  265. package/dist/test_zero_retention_alerts.js.map +1 -0
  266. package/dist/toolHandlers.d.ts +38 -1
  267. package/dist/toolHandlers.d.ts.map +1 -1
  268. package/dist/toolHandlers.js +3856 -938
  269. package/dist/toolHandlers.js.map +1 -1
  270. package/dist/tools.d.ts +20 -0
  271. package/dist/tools.d.ts.map +1 -1
  272. package/dist/tools.js +25 -4
  273. package/dist/tools.js.map +1 -1
  274. package/dist/verify_discoverability.d.ts +2 -0
  275. package/dist/verify_discoverability.d.ts.map +1 -0
  276. package/dist/verify_discoverability.js +53 -0
  277. package/dist/verify_discoverability.js.map +1 -0
  278. package/dist/verify_tools_endpoint.js +16 -3
  279. package/dist/verify_tools_endpoint.js.map +1 -1
  280. package/dist/widgetShell.d.ts +2 -2
  281. package/dist/widgetShell.d.ts.map +1 -1
  282. package/dist/widgetShell.js +1 -1
  283. package/dist/widgetShell.js.map +1 -1
  284. package/package.json +1 -1
  285. package/server.json +4 -32
  286. package/dist/oauthRegisterShim.d.ts +0 -13
  287. package/dist/oauthRegisterShim.d.ts.map +0 -1
  288. package/dist/oauthRegisterShim.js +0 -83
  289. package/dist/oauthRegisterShim.js.map +0 -1
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Verification test for On-Request Expert Query Intercept in consult_human_agent:
3
+ * 1. Confirms unclaimed experts (e.g. Roxane Prieux) are loaded in catalog cache
4
+ * 2. Invokes consult_human_agent with an unclaimed expert
5
+ * 3. Verifies domain-backed intelligence is returned without 404/error
6
+ * 4. Verifies the verification footnote is appended with the correct profile URL
7
+ * 5. Verifies demand webhook format and emission
8
+ */
9
+ import 'dotenv/config';
10
+ import assert from 'assert';
11
+ import crypto from 'crypto';
12
+ import axios from 'axios';
13
+ import { initCatalogCache, getAnalysts } from './catalogCache.js';
14
+ import { createServer } from './toolHandlers.js';
15
+ const SECRET = process.env.FODDA_MCP_SECRET || '';
16
+ const API_KEY = process.env.FODDA_API_KEY || process.env.FODDA_INTERNAL_API_KEY || 'sk_live_abcdef';
17
+ const BASE_URL = process.env.FODDA_API_URL || 'https://api.fodda.ai';
18
+ async function liveFoddaBackend(method, endpoint, apiKey, userId, body) {
19
+ const url = `${BASE_URL}${endpoint}`;
20
+ const timestamp = Date.now().toString();
21
+ const payload = (method === 'POST' || method === 'PATCH')
22
+ ? timestamp + '.' + JSON.stringify(body ?? {})
23
+ : timestamp + '.' + endpoint;
24
+ const signature = crypto.createHmac('sha256', SECRET).update(payload).digest('hex');
25
+ const headers = {
26
+ 'Content-Type': 'application/json',
27
+ 'X-Fodda-Source': 'mcp',
28
+ 'X-Fodda-Billing': 'mcp-orchestrated',
29
+ 'X-API-Key': apiKey || API_KEY,
30
+ 'X-Fodda-Timestamp': timestamp,
31
+ 'X-Fodda-Signature': signature
32
+ };
33
+ const res = await axios({
34
+ method,
35
+ url,
36
+ headers,
37
+ data: body,
38
+ timeout: 30000
39
+ });
40
+ return res.data;
41
+ }
42
+ async function runTest() {
43
+ console.log('=== Testing On-Request Expert Query Intercept in consult_human_agent ===\n');
44
+ console.log('1. Initializing catalog cache with include=unclaimed...');
45
+ await initCatalogCache();
46
+ const analysts = getAnalysts();
47
+ console.log(` Catalog contains ${analysts.length} analysts.`);
48
+ const roxane = analysts.find(a => (a.analyst_id || a.id || a.slug || '').toLowerCase().includes('roxane'));
49
+ assert(roxane, 'Roxane Prieux must be present in cached analysts');
50
+ console.log(` Found expert: ${roxane.name} (status: ${roxane.status}, slug: ${roxane.slug || roxane.id})`);
51
+ assert.strictEqual(roxane.status, 'Unclaimed', 'Roxane Prieux status must be Unclaimed');
52
+ console.log('\n2. Initializing MCP server with tool handlers...');
53
+ const server = await createServer(API_KEY, 'test-verification-user@fodda.ai', liveFoddaBackend, async () => ({}), () => '', () => 'https://mcp.fodda.ai');
54
+ const registeredTools = server._registeredTools || {};
55
+ const consultTool = registeredTools['consult_human_agent'];
56
+ assert(consultTool, 'consult_human_agent tool must be registered');
57
+ const consultFn = consultTool.handler || consultTool.callback || consultTool.execute;
58
+ console.log('\n3. Invoking consult_human_agent for Roxane Prieux (Unclaimed)...');
59
+ const query = 'What are the key clean beauty formulation and sustainable packaging trends for 2026?';
60
+ const result = await consultFn({
61
+ analyst_id: 'roxane-prieux',
62
+ query
63
+ });
64
+ console.log('\n4. Validating response payload...');
65
+ assert(!result.isError, `Tool execution must not return isError: true. Result: ${JSON.stringify(result)}`);
66
+ assert(Array.isArray(result.content) && result.content.length > 0, 'Result must contain content array');
67
+ const fullText = result.content.map((c) => c.text).join('\n');
68
+ console.log('--- Tool Output Snippet ---');
69
+ console.log(fullText.slice(0, 500) + '...\n');
70
+ // Check footnote
71
+ assert(fullText.includes('undergoing onboarding verification'), 'Output must contain onboarding verification note');
72
+ assert(fullText.includes('https://www.fodda.ai/experts/roxane-prieux'), 'Output must contain expert profile URL');
73
+ assert(fullText.includes('available On Request'), 'Output must note that verified human agent is available On Request');
74
+ // Check domain intelligence content
75
+ assert(fullText.toLowerCase().includes('trend') || fullText.toLowerCase().includes('beauty') || fullText.toLowerCase().includes('packaging') || fullText.toLowerCase().includes('formulation'), 'Output must contain domain trend intelligence');
76
+ console.log('✅ Footnote check passed:');
77
+ const footnoteMatch = fullText.match(/\*Note:.*?\*/s);
78
+ if (footnoteMatch) {
79
+ console.log(` "${footnoteMatch[0]}"`);
80
+ }
81
+ console.log('\n5. Checking sources used...');
82
+ if (result.sources_used) {
83
+ console.log(` Total sources returned: ${result.sources_used.length}`);
84
+ const hasProfileSource = result.sources_used.some((s) => (s.url || '').includes('/experts/roxane-prieux'));
85
+ assert(hasProfileSource, 'sources_used must include the expert profile URL');
86
+ console.log(' ✅ Profile source included in sources_used.');
87
+ }
88
+ console.log('\n🎉 ALL ON-REQUEST INTERCEPT VERIFICATION TESTS PASSED!');
89
+ process.exit(0);
90
+ }
91
+ runTest().catch(err => {
92
+ console.error('❌ Test failed:', err);
93
+ process.exit(1);
94
+ });
95
+ //# sourceMappingURL=test_on_request_intercept.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_on_request_intercept.js","sourceRoot":"","sources":["../src/test_on_request_intercept.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,eAAe,CAAC;AACvB,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC;AAClD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,gBAAgB,CAAC;AACpG,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,sBAAsB,CAAC;AAErE,KAAK,UAAU,gBAAgB,CAAC,MAAgC,EAAE,QAAgB,EAAE,MAAe,EAAE,MAAe,EAAE,IAAU;IAC5H,MAAM,GAAG,GAAG,GAAG,QAAQ,GAAG,QAAQ,EAAE,CAAC;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IACxC,MAAM,OAAO,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,OAAO,CAAC;QACrD,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC;QAC9C,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,QAAQ,CAAC;IACjC,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEpF,MAAM,OAAO,GAA2B;QACpC,cAAc,EAAE,kBAAkB;QAClC,gBAAgB,EAAE,KAAK;QACvB,iBAAiB,EAAE,kBAAkB;QACrC,WAAW,EAAE,MAAM,IAAI,OAAO;QAC9B,mBAAmB,EAAE,SAAS;QAC9B,mBAAmB,EAAE,SAAS;KACjC,CAAC;IAEF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC;QACpB,MAAM;QACN,GAAG;QACH,OAAO;QACP,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,KAAK;KACjB,CAAC,CAAC;IACH,OAAO,GAAG,CAAC,IAAI,CAAC;AACpB,CAAC;AAED,KAAK,UAAU,OAAO;IAClB,OAAO,CAAC,GAAG,CAAC,4EAA4E,CAAC,CAAC;IAE1F,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;IACvE,MAAM,gBAAgB,EAAE,CAAC;IAEzB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,OAAO,CAAC,GAAG,CAAC,uBAAuB,QAAQ,CAAC,MAAM,YAAY,CAAC,CAAC;IAEhE,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3G,MAAM,CAAC,MAAM,EAAE,kDAAkD,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,oBAAoB,MAAM,CAAC,IAAI,aAAa,MAAM,CAAC,MAAM,WAAW,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;IAC7G,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,wCAAwC,CAAC,CAAC;IAEzF,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,MAAM,YAAY,CAC7B,OAAO,EACP,iCAAiC,EACjC,gBAAgB,EAChB,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAChB,GAAG,EAAE,CAAC,EAAE,EACR,GAAG,EAAE,CAAC,sBAAsB,CAC/B,CAAC;IAEF,MAAM,eAAe,GAAyB,MAAc,CAAC,gBAAgB,IAAI,EAAE,CAAC;IACpF,MAAM,WAAW,GAAG,eAAe,CAAC,qBAAqB,CAAC,CAAC;IAC3D,MAAM,CAAC,WAAW,EAAE,6CAA6C,CAAC,CAAC;IAEnE,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,IAAI,WAAW,CAAC,QAAQ,IAAI,WAAW,CAAC,OAAO,CAAC;IAErF,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC;IAClF,MAAM,KAAK,GAAG,sFAAsF,CAAC;IACrG,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC;QAC3B,UAAU,EAAE,eAAe;QAC3B,KAAK;KACR,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IACnD,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,yDAAyD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC3G,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,mCAAmC,CAAC,CAAC;IAExG,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC;IAE9C,iBAAiB;IACjB,MAAM,CACF,QAAQ,CAAC,QAAQ,CAAC,oCAAoC,CAAC,EACvD,kDAAkD,CACrD,CAAC;IACF,MAAM,CACF,QAAQ,CAAC,QAAQ,CAAC,4CAA4C,CAAC,EAC/D,wCAAwC,CAC3C,CAAC;IACF,MAAM,CACF,QAAQ,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EACzC,oEAAoE,CACvE,CAAC;IAEF,oCAAoC;IACpC,MAAM,CACF,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,EACvL,+CAA+C,CAClD,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACxC,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACtD,IAAI,aAAa,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAC7C,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,8BAA8B,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;QACxE,MAAM,gBAAgB,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CACzD,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CACnD,CAAC;QACF,MAAM,CAAC,gBAAgB,EAAE,kDAAkD,CAAC,CAAC;QAC7E,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;IACjE,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;IACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC;AAED,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;IAClB,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test_onboarding_consent_and_errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_onboarding_consent_and_errors.d.ts","sourceRoot":"","sources":["../src/test_onboarding_consent_and_errors.ts"],"names":[],"mappings":""}
@@ -0,0 +1,110 @@
1
+ import assert from 'node:assert';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+ console.log('=== Running Onboarding Consent at Step One & Structured Errors Verification ===\n');
8
+ let passed = 0;
9
+ let failed = 0;
10
+ function check(condition, msg) {
11
+ if (condition) {
12
+ console.log(` ✅ ${msg}`);
13
+ passed++;
14
+ }
15
+ else {
16
+ console.error(` ❌ ${msg}`);
17
+ failed++;
18
+ }
19
+ }
20
+ const projectRoot = path.resolve(__dirname, '..');
21
+ const srcDir = fs.existsSync(path.resolve(__dirname, 'systemPrompt.ts')) ? __dirname : path.resolve(projectRoot, 'src');
22
+ const toolHandlersPath = path.resolve(srcDir, 'toolHandlers.ts');
23
+ const systemPromptPath = path.resolve(srcDir, 'systemPrompt.ts');
24
+ const toolsPath = path.resolve(srcDir, 'tools.ts');
25
+ const toolHandlersContent = fs.readFileSync(toolHandlersPath, 'utf8');
26
+ const systemPromptContent = fs.readFileSync(systemPromptPath, 'utf8');
27
+ const toolsContent = fs.readFileSync(toolsPath, 'utf8');
28
+ // ---------------------------------------------------------------------------
29
+ // 1. Tool Versions in src/tools.ts
30
+ // ---------------------------------------------------------------------------
31
+ console.log('1. Verifying Tool Versions in src/tools.ts...');
32
+ check(toolsContent.includes('submit_basic_info: "1.2.0"'), 'submit_basic_info is bumped to 1.2.0');
33
+ check(toolsContent.includes('begin_expert_onboarding: "1.1.0"'), 'begin_expert_onboarding is bumped to 1.1.0');
34
+ check(toolsContent.includes('submit_mcp_source: "1.1.0"'), 'submit_mcp_source is bumped to 1.1.0');
35
+ check(toolsContent.includes('finalize_byo_mcp_onboarding: "1.1.0"'), 'finalize_byo_mcp_onboarding is bumped to 1.1.0');
36
+ check(toolsContent.includes('submit_expertise_analysis: "1.1.0"'), 'submit_expertise_analysis is bumped to 1.1.0');
37
+ check(toolsContent.includes('get_detected_themes: "1.1.0"'), 'get_detected_themes is bumped to 1.1.0');
38
+ check(toolsContent.includes('confirm_themes: "1.1.0"'), 'confirm_themes is bumped to 1.1.0');
39
+ check(toolsContent.includes('get_onboarding_status: "1.1.0"'), 'get_onboarding_status is bumped to 1.1.0');
40
+ check(toolsContent.includes('schedule_interview: "1.1.0"'), 'schedule_interview is bumped to 1.1.0');
41
+ check(toolsContent.includes('expert_onboarding_research: "1.1.0"'), 'expert_onboarding_research is bumped to 1.1.0');
42
+ // ---------------------------------------------------------------------------
43
+ // 2. Truthful Persistence Copy & Definition of Done Grep
44
+ // ---------------------------------------------------------------------------
45
+ console.log('\n2. Verifying Truthful Persistence Copy (Grep Invariants)...');
46
+ // Brief Definition of Done:
47
+ // grep -rn -i "nothing is saved|held in this chat|lives only in this conversation" src/
48
+ // returns no false persistence claims. Only the scoped "still drafting" line remains.
49
+ const falsePersistenceRegex = /nothing is saved(?!.*until you submit that step)|held in this chat|lives only in this conversation/i;
50
+ check(!falsePersistenceRegex.test(toolHandlersContent), 'toolHandlers.ts contains no false persistence claims');
51
+ check(!falsePersistenceRegex.test(systemPromptContent), 'systemPrompt.ts contains no false persistence claims');
52
+ // Verify truthful copy exists
53
+ check(toolHandlersContent.includes('Once you accept the terms, Fodda saves each step as you complete it.'), 'toolHandlers.ts contains "Once you accept the terms, Fodda saves each step as you complete it."');
54
+ check(systemPromptContent.includes('Once you accept the terms, Fodda saves each step as you complete it.'), 'systemPrompt.ts contains "Once you accept the terms, Fodda saves each step as you complete it."');
55
+ check(toolHandlersContent.includes("Anything I'm still drafting with you, like your voice study before you submit it, lives only in this chat until you submit that step."), 'toolHandlers.ts contains scoped drafting persistence line');
56
+ check(systemPromptContent.includes("Anything I'm still drafting with you, like your voice study before you submit it, lives only in this chat until you submit that step."), 'systemPrompt.ts contains scoped drafting persistence line');
57
+ check(toolHandlersContent.includes("Your profile is saved once you accept the terms. Your MCP connection is only checked, not saved, until you submit at the end."), 'toolHandlers.ts contains BYO-MCP truthful persistence copy');
58
+ check(systemPromptContent.includes("Your profile is saved once you accept the terms. Your MCP connection is only checked, not saved, until you submit at the end."), 'systemPrompt.ts contains BYO-MCP truthful persistence copy');
59
+ // ---------------------------------------------------------------------------
60
+ // 3. Structured Error Format & Code Set Coverage
61
+ // ---------------------------------------------------------------------------
62
+ console.log('\n3. Verifying Structured Error Infrastructure...');
63
+ const requiredCodes = [
64
+ 'credentials_missing',
65
+ 'terms_required',
66
+ 'record_not_found',
67
+ 'research_needs_basic_info',
68
+ 'themes_not_ready',
69
+ 'questions_failed',
70
+ 'interview_slot_invalid',
71
+ 'interview_already_scheduled',
72
+ 'mcp_probe_failed',
73
+ 'mcp_auth_unsupported',
74
+ 'upstream_error'
75
+ ];
76
+ for (const code of requiredCodes) {
77
+ check(toolHandlersContent.includes(`${code}:`), `ONBOARDING_ERROR_METADATA defines error code "${code}"`);
78
+ }
79
+ // ---------------------------------------------------------------------------
80
+ // 4. get_onboarding_status Next-Step Rendering
81
+ // ---------------------------------------------------------------------------
82
+ console.log('\n4. Verifying get_onboarding_status Next-Action & Next-Tool Rendering...');
83
+ check(toolHandlersContent.includes('**Where you are:** ${label}. **Next step for you:** ${nextAction}'), 'get_onboarding_status formats prose as "**Where you are:** <status label>. **Next step for you:** <next_action>"');
84
+ check(toolHandlersContent.includes('next_tool: nextTool') && toolHandlersContent.includes('next_action: nextAction'), 'get_onboarding_status passes next_tool and next_action in JSON block');
85
+ check(toolHandlersContent.includes('Interview scheduled') && toolHandlersContent.includes('Google Meet'), 'deriveStatusFlow distinguishes booked bot with Recall Join At and Google Meet message');
86
+ // ---------------------------------------------------------------------------
87
+ // 5. schedule_interview Next-Step Null & Reassurance
88
+ // ---------------------------------------------------------------------------
89
+ console.log('\n5. Verifying schedule_interview Output...');
90
+ check(toolHandlersContent.includes('next_step: null'), 'schedule_interview returns next_step: null on success');
91
+ check(toolHandlersContent.includes('After the interview, Fodda reviews your Human Agent and emails you. You can check progress any time with get_onboarding_status.'), 'schedule_interview includes exact closing reassurance line');
92
+ // ---------------------------------------------------------------------------
93
+ // 6. Resume on Start in begin_expert_onboarding
94
+ // ---------------------------------------------------------------------------
95
+ console.log('\n6. Verifying begin_expert_onboarding Resume Behavior...');
96
+ check(toolHandlersContent.includes('result.inProgress') && toolHandlersContent.includes("You've already started, so let's pick up at <${resumeStep}>."), 'begin_expert_onboarding handles inProgress with "You\'ve already started, so let\'s pick up at <step>"');
97
+ check(toolHandlersContent.includes("status: 'resumed'") && toolHandlersContent.includes('resume: {'), 'begin_expert_onboarding returns resume object payload');
98
+ // ---------------------------------------------------------------------------
99
+ // 7. submit_basic_info Consent Point & Relaxed Later Steps
100
+ // ---------------------------------------------------------------------------
101
+ console.log('\n7. Verifying submit_basic_info Consent Point & Relaxed Subsequent Checks...');
102
+ check(toolHandlersContent.includes('termsAccepted: z.boolean().describe("The expert must explicitly accept the Fodda Terms of Service'), 'submit_basic_info has required termsAccepted: boolean in schema');
103
+ check(toolHandlersContent.includes('if (termsAccepted !== true)') && toolHandlersContent.includes("code: 'terms_required'"), 'submit_basic_info refuses with terms_required error if termsAccepted !== true');
104
+ check(toolHandlersContent.includes('termsAccepted: z.boolean().optional().describe("Optional if already accepted at basic info'), 'submit_expertise_analysis marks termsAccepted optional');
105
+ check(toolHandlersContent.includes('termsAccepted: z.boolean().optional().describe("Optional if already accepted at basic info'), 'finalize_byo_mcp_onboarding marks termsAccepted optional');
106
+ console.log(`\nVerification Summary: ${passed} passed, ${failed} failed.`);
107
+ if (failed > 0) {
108
+ process.exit(1);
109
+ }
110
+ //# sourceMappingURL=test_onboarding_consent_and_errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_onboarding_consent_and_errors.js","sourceRoot":"","sources":["../src/test_onboarding_consent_and_errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test_onboarding_live_scenarios.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_onboarding_live_scenarios.d.ts","sourceRoot":"","sources":["../src/test_onboarding_live_scenarios.ts"],"names":[],"mappings":""}
@@ -0,0 +1,189 @@
1
+ import assert from 'node:assert';
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { createServer } from './toolHandlers.js';
4
+ console.log('=== Running Live Scenario Tests for Onboarding Tools ===\n');
5
+ let passed = 0;
6
+ let failed = 0;
7
+ function check(condition, msg) {
8
+ if (condition) {
9
+ console.log(` ✅ ${msg}`);
10
+ passed++;
11
+ }
12
+ else {
13
+ console.error(` ❌ ${msg}`);
14
+ failed++;
15
+ }
16
+ }
17
+ async function run() {
18
+ let mockResponse = {};
19
+ let mockStatus = 200;
20
+ let mockShouldThrow = false;
21
+ let mockErrorData = null;
22
+ const mockFoddaRequest = async (method, path, key, uid, body) => {
23
+ if (mockShouldThrow) {
24
+ const err = new Error(mockErrorData?.message || 'Mock Network Error');
25
+ err.response = { status: mockStatus, data: mockErrorData };
26
+ throw err;
27
+ }
28
+ return mockResponse;
29
+ };
30
+ const server = await createServer('test-api-key', 'test-user@example.com', mockFoddaRequest, (async () => ({})), () => 'widget-id', () => 'https://mcp.fodda.ai');
31
+ const registeredTools = server._registeredTools;
32
+ // Helper to call a tool handler directly
33
+ const callTool = async (name, args) => {
34
+ const tool = registeredTools[name];
35
+ if (!tool)
36
+ throw new Error(`Tool ${name} not found`);
37
+ return await tool.handler(args, {});
38
+ };
39
+ // 1. Forced Failure: terms_required on submit_basic_info
40
+ console.log('1. Testing forced failure: terms_required...');
41
+ const termsRes = await callTool('submit_basic_info', {
42
+ name: 'Jane Doe',
43
+ role: 'Founder',
44
+ knowledgeArea: 'Retail AI',
45
+ termsAccepted: false
46
+ });
47
+ check(termsRes.isError === true, 'termsAccepted: false returns isError: true');
48
+ const termsText = termsRes.content[0].text;
49
+ check(termsText.includes('```json'), 'terms_required includes fenced JSON block');
50
+ const termsJsonMatch = termsText.match(/```json\n([\s\S]*?)\n```/);
51
+ const termsJson = JSON.parse(termsJsonMatch[1]);
52
+ check(termsJson.error.code === 'terms_required', 'error code is terms_required');
53
+ check(termsJson.error.cause === 'Terms not accepted yet.', 'error cause matches');
54
+ check(termsJson.error.next_action.includes('submit_basic_info again'), 'error next_action matches');
55
+ // 2. Forced Failure: mcp_auth_unsupported on submit_mcp_source
56
+ console.log('\n2. Testing forced failure: mcp_auth_unsupported...');
57
+ const authRes = await callTool('submit_mcp_source', {
58
+ mcpUrl: 'https://games.thisisdelightful.com/mcp',
59
+ mcpAuthType: 'bearer'
60
+ });
61
+ check(authRes.isError === true, 'mcpAuthType: bearer returns isError: true');
62
+ const authText = authRes.content[0].text;
63
+ const authJsonMatch = authText.match(/```json\n([\s\S]*?)\n```/);
64
+ const authJson = JSON.parse(authJsonMatch[1]);
65
+ check(authJson.error.code === 'mcp_auth_unsupported', 'error code is mcp_auth_unsupported');
66
+ check(authJson.error.next_action.includes("authType 'none'"), 'next_action guides to authType none');
67
+ // 3. Forced Failure: interview_slot_invalid on schedule_interview
68
+ console.log('\n3. Testing forced failure: interview_slot_invalid...');
69
+ mockShouldThrow = true;
70
+ mockStatus = 400;
71
+ mockErrorData = { error: 'interview_slot_invalid', message: 'The requested interview time is outside 15 min to 30 days.' };
72
+ const slotRes = await callTool('schedule_interview', {
73
+ datetime: '2026-10-02T16:00:00.000Z'
74
+ });
75
+ check(slotRes.isError === true, 'invalid slot returns isError: true');
76
+ const slotText = slotRes.content[0].text;
77
+ const slotJsonMatch = slotText.match(/```json\n([\s\S]*?)\n```/);
78
+ const slotJson = JSON.parse(slotJsonMatch[1]);
79
+ check(slotJson.error.code === 'interview_slot_invalid', 'error code is interview_slot_invalid');
80
+ check(slotJson.error.next_action.includes('15 minutes and 30 days'), 'next_action guides on scheduling window');
81
+ // 4. Forced Failure: upstream_error fallback
82
+ console.log('\n4. Testing forced failure: upstream_error...');
83
+ mockShouldThrow = true;
84
+ mockStatus = 500;
85
+ mockErrorData = { message: 'Database connection failed' };
86
+ const upstreamRes = await callTool('get_detected_themes', {});
87
+ check(upstreamRes.isError === true, 'upstream 500 returns isError: true');
88
+ const upstreamText = upstreamRes.content[0].text;
89
+ const upstreamJsonMatch = upstreamText.match(/```json\n([\s\S]*?)\n```/);
90
+ const upstreamJson = JSON.parse(upstreamJsonMatch[1]);
91
+ check(upstreamJson.error.code === 'upstream_error', 'fallback error code is upstream_error');
92
+ check(upstreamJson.error.cause === 'Database connection failed', 'original error message preserved in cause');
93
+ // Reset mock
94
+ mockShouldThrow = false;
95
+ mockStatus = 200;
96
+ mockErrorData = null;
97
+ // 5. get_onboarding_status reachable statuses
98
+ console.log('\n5. Testing get_onboarding_status reachable statuses...');
99
+ const testStatuses = [
100
+ {
101
+ status: 'not_started',
102
+ expectedTool: 'begin_expert_onboarding',
103
+ expectedAction: 'Start onboarding to set up your Human Agent.'
104
+ },
105
+ {
106
+ status: 'basic_info_submitted',
107
+ expectedTool: 'expert_onboarding_research',
108
+ expectedAction: 'Next, Fodda researches your published work so your interview can focus on your thinking, not your CV.'
109
+ },
110
+ {
111
+ status: 'research_complete',
112
+ expectedTool: 'submit_expertise_analysis',
113
+ expectedAction: 'Share your voice study and expertise map so we can find your core themes.'
114
+ },
115
+ {
116
+ status: 'analysis_submitted',
117
+ expectedTool: 'get_detected_themes',
118
+ expectedAction: 'Review the themes Fodda found in your work and confirm the ones that fit, so we can prepare your interview questions.'
119
+ },
120
+ {
121
+ status: 'awaiting_interview',
122
+ expectedTool: 'schedule_interview',
123
+ expectedAction: 'Book your 15–20 minute expertise interview, now or at a time that suits you.'
124
+ },
125
+ {
126
+ status: 'awaiting_interview',
127
+ recallBotId: 'bot-12345',
128
+ recallJoinAt: 'Friday, Oct 3 at 2:00 PM EDT',
129
+ expectedTool: null,
130
+ expectedAction: 'Your interview is booked for Friday, Oct 3 at 2:00 PM EDT. The interviewer will join your Google Meet.'
131
+ },
132
+ {
133
+ status: 'pending_approval',
134
+ expectedTool: null,
135
+ expectedAction: "You're done. Fodda is reviewing your Human Agent and will email you before it goes live."
136
+ },
137
+ {
138
+ status: 'active',
139
+ expectedTool: null,
140
+ expectedAction: 'Your Human Agent is live.'
141
+ }
142
+ ];
143
+ for (const testCase of testStatuses) {
144
+ mockResponse = {
145
+ status: testCase.status,
146
+ analystId: 'recAnalyst123',
147
+ recallBotId: testCase.recallBotId,
148
+ recallJoinAt: testCase.recallJoinAt
149
+ };
150
+ const statusRes = await callTool('get_onboarding_status', {});
151
+ check(statusRes.isError !== true, `status ${testCase.status} returns clean result`);
152
+ const prose = statusRes.content[0].text;
153
+ const payload = JSON.parse(statusRes.content[1].text);
154
+ check(prose.startsWith('**Where you are:**') && prose.includes('**Next step for you:**'), `prose format matches for ${testCase.status}`);
155
+ check(prose.includes(testCase.expectedAction), `prose includes expected action for ${testCase.status}`);
156
+ check(payload.next_tool === testCase.expectedTool, `payload next_tool is ${testCase.expectedTool} for ${testCase.status}`);
157
+ check(payload.next_action === testCase.expectedAction, `payload next_action matches for ${testCase.status}`);
158
+ }
159
+ // 6. schedule_interview success: next_step: null and closing reassurance
160
+ console.log('\n6. Testing schedule_interview success...');
161
+ mockResponse = { scheduled: true, joinUrl: 'https://meet.google.com/abc-defg-hij' };
162
+ const schedRes = await callTool('schedule_interview', { now: true });
163
+ const schedProse = schedRes.content[0].text;
164
+ const schedPayload = JSON.parse(schedRes.content[1].text);
165
+ check(schedPayload.next_step === null, 'schedule_interview returns next_step: null');
166
+ check(schedProse.includes('After the interview, Fodda reviews your Human Agent and emails you. You can check progress any time with get_onboarding_status.'), 'schedule_interview includes closing reassurance line');
167
+ // 7. begin_expert_onboarding with inProgress
168
+ console.log('\n7. Testing begin_expert_onboarding resume behavior...');
169
+ mockResponse = {
170
+ inProgress: {
171
+ analystId: 'rec999',
172
+ status: 'analysis_submitted'
173
+ }
174
+ };
175
+ const resumeRes = await callTool('begin_expert_onboarding', {});
176
+ const resumeProse = resumeRes.content[0].text;
177
+ const resumePayload = JSON.parse(resumeRes.content[1].text);
178
+ check(resumePayload.status === 'resumed', 'status is resumed');
179
+ check(resumePayload.resume.next_step === 'get_detected_themes', 'resume next_step is get_detected_themes');
180
+ check(resumeProse.includes("You've already started, so let's pick up at <get_detected_themes>."), 'prose includes "You\'ve already started, so let\'s pick up at <get_detected_themes>."');
181
+ console.log(`\nLive Scenarios Verification Summary: ${passed} passed, ${failed} failed.`);
182
+ if (failed > 0)
183
+ process.exit(1);
184
+ }
185
+ run().catch(err => {
186
+ console.error('Fatal error in test runner:', err);
187
+ process.exit(1);
188
+ });
189
+ //# sourceMappingURL=test_onboarding_live_scenarios.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_onboarding_live_scenarios.js","sourceRoot":"","sources":["../src/test_onboarding_live_scenarios.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAC;AAE1E,IAAI,MAAM,GAAG,CAAC,CAAC;AACf,IAAI,MAAM,GAAG,CAAC,CAAC;AAEf,SAAS,KAAK,CAAC,SAAkB,EAAE,GAAW;IAC1C,IAAI,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QAC1B,MAAM,EAAE,CAAC;IACb,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QAC5B,MAAM,EAAE,CAAC;IACb,CAAC;AACL,CAAC;AAED,KAAK,UAAU,GAAG;IACd,IAAI,YAAY,GAAQ,EAAE,CAAC;IAC3B,IAAI,UAAU,GAAG,GAAG,CAAC;IACrB,IAAI,eAAe,GAAG,KAAK,CAAC;IAC5B,IAAI,aAAa,GAAQ,IAAI,CAAC;IAE9B,MAAM,gBAAgB,GAAG,KAAK,EAAE,MAAc,EAAE,IAAY,EAAE,GAAY,EAAE,GAAY,EAAE,IAAU,EAAE,EAAE;QACpG,IAAI,eAAe,EAAE,CAAC;YAClB,MAAM,GAAG,GAAQ,IAAI,KAAK,CAAC,aAAa,EAAE,OAAO,IAAI,oBAAoB,CAAC,CAAC;YAC3E,GAAG,CAAC,QAAQ,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;YAC3D,MAAM,GAAG,CAAC;QACd,CAAC;QACD,OAAO,YAAY,CAAC;IACxB,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,YAAY,CAC7B,cAAc,EACd,uBAAuB,EACvB,gBAAuB,EACvB,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAQ,EACzB,GAAG,EAAE,CAAC,WAAW,EACjB,GAAG,EAAE,CAAC,sBAAsB,CAC/B,CAAC;IAEF,MAAM,eAAe,GAAI,MAAc,CAAC,gBAAgB,CAAC;IAEzD,yCAAyC;IACzC,MAAM,QAAQ,GAAG,KAAK,EAAE,IAAY,EAAE,IAAS,EAAE,EAAE;QAC/C,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,YAAY,CAAC,CAAC;QACrD,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACxC,CAAC,CAAC;IAEF,yDAAyD;IACzD,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,mBAAmB,EAAE;QACjD,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,SAAS;QACf,aAAa,EAAE,WAAW;QAC1B,aAAa,EAAE,KAAK;KACvB,CAAC,CAAC;IACH,KAAK,CAAC,QAAQ,CAAC,OAAO,KAAK,IAAI,EAAE,4CAA4C,CAAC,CAAC;IAC/E,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3C,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,2CAA2C,CAAC,CAAC;IAClF,MAAM,cAAc,GAAG,SAAS,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,cAAe,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,8BAA8B,CAAC,CAAC;IACjF,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,KAAK,yBAAyB,EAAE,qBAAqB,CAAC,CAAC;IAClF,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,2BAA2B,CAAC,CAAC;IAEpG,+DAA+D;IAC/D,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;IACpE,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,mBAAmB,EAAE;QAChD,MAAM,EAAE,wCAAwC;QAChD,WAAW,EAAE,QAAQ;KACxB,CAAC,CAAC;IACH,KAAK,CAAC,OAAO,CAAC,OAAO,KAAK,IAAI,EAAE,2CAA2C,CAAC,CAAC;IAC7E,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,aAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,sBAAsB,EAAE,oCAAoC,CAAC,CAAC;IAC5F,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,qCAAqC,CAAC,CAAC;IAErG,kEAAkE;IAClE,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;IACtE,eAAe,GAAG,IAAI,CAAC;IACvB,UAAU,GAAG,GAAG,CAAC;IACjB,aAAa,GAAG,EAAE,KAAK,EAAE,wBAAwB,EAAE,OAAO,EAAE,4DAA4D,EAAE,CAAC;IAC3H,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,oBAAoB,EAAE;QACjD,QAAQ,EAAE,0BAA0B;KACvC,CAAC,CAAC;IACH,KAAK,CAAC,OAAO,CAAC,OAAO,KAAK,IAAI,EAAE,oCAAoC,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,aAAc,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,wBAAwB,EAAE,sCAAsC,CAAC,CAAC;IAChG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,yCAAyC,CAAC,CAAC;IAEhH,6CAA6C;IAC7C,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;IAC9D,eAAe,GAAG,IAAI,CAAC;IACvB,UAAU,GAAG,GAAG,CAAC;IACjB,aAAa,GAAG,EAAE,OAAO,EAAE,4BAA4B,EAAE,CAAC;IAC1D,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;IAC9D,KAAK,CAAC,WAAW,CAAC,OAAO,KAAK,IAAI,EAAE,oCAAoC,CAAC,CAAC;IAC1E,MAAM,YAAY,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjD,MAAM,iBAAiB,GAAG,YAAY,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACzE,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,uCAAuC,CAAC,CAAC;IAC7F,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,KAAK,4BAA4B,EAAE,2CAA2C,CAAC,CAAC;IAE9G,aAAa;IACb,eAAe,GAAG,KAAK,CAAC;IACxB,UAAU,GAAG,GAAG,CAAC;IACjB,aAAa,GAAG,IAAI,CAAC;IAErB,8CAA8C;IAC9C,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;IAExE,MAAM,YAAY,GAAG;QACjB;YACI,MAAM,EAAE,aAAa;YACrB,YAAY,EAAE,yBAAyB;YACvC,cAAc,EAAE,8CAA8C;SACjE;QACD;YACI,MAAM,EAAE,sBAAsB;YAC9B,YAAY,EAAE,4BAA4B;YAC1C,cAAc,EAAE,uGAAuG;SAC1H;QACD;YACI,MAAM,EAAE,mBAAmB;YAC3B,YAAY,EAAE,2BAA2B;YACzC,cAAc,EAAE,2EAA2E;SAC9F;QACD;YACI,MAAM,EAAE,oBAAoB;YAC5B,YAAY,EAAE,qBAAqB;YACnC,cAAc,EAAE,uHAAuH;SAC1I;QACD;YACI,MAAM,EAAE,oBAAoB;YAC5B,YAAY,EAAE,oBAAoB;YAClC,cAAc,EAAE,8EAA8E;SACjG;QACD;YACI,MAAM,EAAE,oBAAoB;YAC5B,WAAW,EAAE,WAAW;YACxB,YAAY,EAAE,8BAA8B;YAC5C,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,wGAAwG;SAC3H;QACD;YACI,MAAM,EAAE,kBAAkB;YAC1B,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,0FAA0F;SAC7G;QACD;YACI,MAAM,EAAE,QAAQ;YAChB,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,2BAA2B;SAC9C;KACJ,CAAC;IAEF,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QAClC,YAAY,GAAG;YACX,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,SAAS,EAAE,eAAe;YAC1B,WAAW,EAAG,QAAgB,CAAC,WAAW;YAC1C,YAAY,EAAG,QAAgB,CAAC,YAAY;SAC/C,CAAC;QACF,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;QAC9D,KAAK,CAAC,SAAS,CAAC,OAAO,KAAK,IAAI,EAAE,UAAU,QAAQ,CAAC,MAAM,uBAAuB,CAAC,CAAC;QACpF,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEtD,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,oBAAoB,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,4BAA4B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACzI,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,sCAAsC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACxG,KAAK,CAAC,OAAO,CAAC,SAAS,KAAK,QAAQ,CAAC,YAAY,EAAE,wBAAwB,QAAQ,CAAC,YAAY,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3H,KAAK,CAAC,OAAO,CAAC,WAAW,KAAK,QAAQ,CAAC,cAAc,EAAE,mCAAmC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACjH,CAAC;IAED,yEAAyE;IACzE,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAC1D,YAAY,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,sCAAsC,EAAE,CAAC;IACpF,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,oBAAoB,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IACrE,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC1D,KAAK,CAAC,YAAY,CAAC,SAAS,KAAK,IAAI,EAAE,4CAA4C,CAAC,CAAC;IACrF,KAAK,CACD,UAAU,CAAC,QAAQ,CAAC,iIAAiI,CAAC,EACtJ,sDAAsD,CACzD,CAAC;IAEF,6CAA6C;IAC7C,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;IACvE,YAAY,GAAG;QACX,UAAU,EAAE;YACR,SAAS,EAAE,QAAQ;YACnB,MAAM,EAAE,oBAAoB;SAC/B;KACJ,CAAC;IACF,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC;IAChE,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9C,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC5D,KAAK,CAAC,aAAa,CAAC,MAAM,KAAK,SAAS,EAAE,mBAAmB,CAAC,CAAC;IAC/D,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,SAAS,KAAK,qBAAqB,EAAE,yCAAyC,CAAC,CAAC;IAC3G,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,oEAAoE,CAAC,EAAE,uFAAuF,CAAC,CAAC;IAE3L,OAAO,CAAC,GAAG,CAAC,0CAA0C,MAAM,YAAY,MAAM,UAAU,CAAC,CAAC;IAC1F,IAAI,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;IACd,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;IAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test_referral_live.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_referral_live.d.ts","sourceRoot":"","sources":["../src/test_referral_live.ts"],"names":[],"mappings":""}
@@ -0,0 +1,33 @@
1
+ import dotenv from 'dotenv';
2
+ dotenv.config();
3
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
4
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
5
+ const DEPLOYED_MCP_URL = process.env.TEST_URL || 'https://mcp.fodda.ai/mcp';
6
+ const FODDA_API_KEY = process.env.FODDA_API_KEY || 'sk_live_abcdef';
7
+ async function testReferralLive() {
8
+ console.log(`=== Testing Referral Logic on Live Deployed MCP Server (${DEPLOYED_MCP_URL}) ===\n`);
9
+ const transport = new StreamableHTTPClientTransport(new URL(`${DEPLOYED_MCP_URL}?api_key=${FODDA_API_KEY}&session_kind=internal-test`));
10
+ const client = new Client({ name: 'live-referral-verifier', version: '1.0.0' });
11
+ await client.connect(transport);
12
+ console.log('1. Calling consult_analyst with a Digital Twin ID (anu-lingala-macro)...');
13
+ const result = await client.callTool({
14
+ name: 'consult_analyst',
15
+ arguments: {
16
+ analyst_id: 'anu-lingala-macro',
17
+ query: 'Test referral check'
18
+ }
19
+ });
20
+ const text = result.content[0]?.text || '';
21
+ console.log(`\nResult output:\n"${text}"\n`);
22
+ if (text.includes('Human Agent') && text.includes('consult_human_agent')) {
23
+ console.log('✅ PASS: consult_analyst returned referral to consult_human_agent!');
24
+ }
25
+ else {
26
+ console.log('ℹ️ NOTE: Upstream API has not yet deployed updated /v1/analysts response with type=human_agent.');
27
+ }
28
+ await client.close();
29
+ }
30
+ testReferralLive().catch(err => {
31
+ console.error('❌ Error:', err.message || err);
32
+ });
33
+ //# sourceMappingURL=test_referral_live.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_referral_live.js","sourceRoot":"","sources":["../src/test_referral_live.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAEnG,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,0BAA0B,CAAC;AAC5E,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,gBAAgB,CAAC;AAEpE,KAAK,UAAU,gBAAgB;IAC3B,OAAO,CAAC,GAAG,CAAC,2DAA2D,gBAAgB,SAAS,CAAC,CAAC;IAElG,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAC/C,IAAI,GAAG,CAAC,GAAG,gBAAgB,YAAY,aAAa,6BAA6B,CAAC,CACrF,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAChF,MAAM,MAAM,CAAC,OAAO,CAAC,SAAgB,CAAC,CAAC;IAEvC,OAAO,CAAC,GAAG,CAAC,0EAA0E,CAAC,CAAC;IACxF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC;QACjC,IAAI,EAAE,iBAAiB;QACvB,SAAS,EAAE;YACP,UAAU,EAAE,mBAAmB;YAC/B,KAAK,EAAE,qBAAqB;SAC/B;KACJ,CAAC,CAAC;IAEH,MAAM,IAAI,GAAI,MAAM,CAAC,OAAe,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,KAAK,CAAC,CAAC;IAE7C,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAC;IACrF,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,iGAAiG,CAAC,CAAC;IACnH,CAAC;IAED,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACzB,CAAC;AAED,gBAAgB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;IAC3B,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC;AAClD,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test_referral_piers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_referral_piers.d.ts","sourceRoot":"","sources":["../src/test_referral_piers.ts"],"names":[],"mappings":""}
@@ -0,0 +1,33 @@
1
+ import dotenv from 'dotenv';
2
+ dotenv.config();
3
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
4
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
5
+ const DEPLOYED_MCP_URL = process.env.TEST_URL || 'https://mcp.fodda.ai/mcp';
6
+ const FODDA_API_KEY = process.env.FODDA_API_KEY || 'sk_live_abcdef';
7
+ async function testReferralPiers() {
8
+ console.log(`=== Testing Referral Logic on Deployed Revision (fodda-mcp-00441-nfx) ===\n`);
9
+ const transport = new StreamableHTTPClientTransport(new URL(`${DEPLOYED_MCP_URL}?api_key=${FODDA_API_KEY}&session_kind=internal-test`));
10
+ const client = new Client({ name: 'live-referral-verifier', version: '1.0.0' });
11
+ await client.connect(transport);
12
+ console.log('Calling consult_analyst with Digital Twin ID: piers-fawkes-psfk...');
13
+ const result = await client.callTool({
14
+ name: 'consult_analyst',
15
+ arguments: {
16
+ analyst_id: 'piers-fawkes-psfk',
17
+ query: 'What are the top retail trend signals?'
18
+ }
19
+ });
20
+ const text = result.content[0]?.text || '';
21
+ console.log(`\nResult output:\n"${text}"\n`);
22
+ if (text.includes('Human Agent') || text.includes('consult_human_agent')) {
23
+ console.log('🎉 SUCCESS: consult_analyst returned referral to consult_human_agent for piers-fawkes-psfk!');
24
+ }
25
+ else {
26
+ console.log('ℹ️ Result returned standard consult text.');
27
+ }
28
+ await client.close();
29
+ }
30
+ testReferralPiers().catch(err => {
31
+ console.error('❌ Error:', err.message || err);
32
+ });
33
+ //# sourceMappingURL=test_referral_piers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_referral_piers.js","sourceRoot":"","sources":["../src/test_referral_piers.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAEnG,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,0BAA0B,CAAC;AAC5E,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,gBAAgB,CAAC;AAEpE,KAAK,UAAU,iBAAiB;IAC5B,OAAO,CAAC,GAAG,CAAC,6EAA6E,CAAC,CAAC;IAE3F,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAC/C,IAAI,GAAG,CAAC,GAAG,gBAAgB,YAAY,aAAa,6BAA6B,CAAC,CACrF,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAChF,MAAM,MAAM,CAAC,OAAO,CAAC,SAAgB,CAAC,CAAC;IAEvC,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC;IAClF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC;QACjC,IAAI,EAAE,iBAAiB;QACvB,SAAS,EAAE;YACP,UAAU,EAAE,mBAAmB;YAC/B,KAAK,EAAE,wCAAwC;SAClD;KACJ,CAAC,CAAC;IAEH,MAAM,IAAI,GAAI,MAAM,CAAC,OAAe,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,KAAK,CAAC,CAAC;IAE7C,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,6FAA6F,CAAC,CAAC;IAC/G,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACzB,CAAC;AAED,iBAAiB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;IAC5B,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC;AAClD,CAAC,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Comprehensive Test Suite for 5-Pillar Editorial & Network Synthesis (v1.46.44).
3
+ *
4
+ * Uses realistic API response fixtures:
5
+ * - Evidence as object `{ statistics: [...], case_studies: [...] }`
6
+ * - Real catalog cache state with `setCachedCatalogForTesting`
7
+ * - Real human twin fields (`isVerifiedRealPerson`, `expertSlug`)
8
+ * - `relevance_score` fields
9
+ *
10
+ * Tests:
11
+ * 1. Primary Report Graph Resolution & Row Partitioning
12
+ * 2. Deduplication of Network Signals against Primary Evidence
13
+ * 3. Human Expert Digital Twin matching (valid match vs. 0-overlap decline)
14
+ * 4. 5-Pillar Payload generation (JSON keys + Pre-rendered Markdown)
15
+ * 5. Mechanical fallback path verification
16
+ * 6. Non-leakage of token / SPT mechanics
17
+ * 7. Absolute HTTPS URLs in all links
18
+ * 8. Honest empty-coverage hook framing
19
+ */
20
+ export {};
21
+ //# sourceMappingURL=test_report_editorial_briefing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test_report_editorial_briefing.d.ts","sourceRoot":"","sources":["../src/test_report_editorial_briefing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG"}