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.
- package/README.md +14 -94
- package/dist/agents/fodda-researcher/skills.d.ts +1 -1
- package/dist/agents/fodda-researcher/skills.d.ts.map +1 -1
- package/dist/agents/fodda-researcher/skills.js +1 -1
- package/dist/brandTemplate.d.ts +1 -1
- package/dist/brandTemplate.d.ts.map +1 -1
- package/dist/brandTemplate.js +162 -74
- package/dist/brandTemplate.js.map +1 -1
- package/dist/catalogCache.d.ts +29 -1
- package/dist/catalogCache.d.ts.map +1 -1
- package/dist/catalogCache.js +267 -16
- package/dist/catalogCache.js.map +1 -1
- package/dist/coverageRelevance.d.ts +97 -2
- package/dist/coverageRelevance.d.ts.map +1 -1
- package/dist/coverageRelevance.js +959 -164
- package/dist/coverageRelevance.js.map +1 -1
- package/dist/editorialFill.d.ts +5 -0
- package/dist/editorialFill.d.ts.map +1 -1
- package/dist/editorialFill.js +1 -1
- package/dist/editorialFill.js.map +1 -1
- package/dist/enrichment.d.ts +26 -0
- package/dist/enrichment.d.ts.map +1 -1
- package/dist/enrichment.js +394 -31
- package/dist/enrichment.js.map +1 -1
- package/dist/errorHandling.d.ts +35 -7
- package/dist/errorHandling.d.ts.map +1 -1
- package/dist/errorHandling.js +225 -155
- package/dist/errorHandling.js.map +1 -1
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +351 -143
- package/dist/index.js.map +1 -1
- package/dist/jobs/jlens_quarterly_sweep.d.ts +62 -0
- package/dist/jobs/jlens_quarterly_sweep.d.ts.map +1 -0
- package/dist/jobs/jlens_quarterly_sweep.js +160 -0
- package/dist/jobs/jlens_quarterly_sweep.js.map +1 -0
- package/dist/pricingCache.d.ts.map +1 -1
- package/dist/pricingCache.js +41 -1
- package/dist/pricingCache.js.map +1 -1
- package/dist/queryCache.d.ts.map +1 -1
- package/dist/queryCache.js +2 -0
- package/dist/queryCache.js.map +1 -1
- package/dist/reportBriefing.d.ts +89 -0
- package/dist/reportBriefing.d.ts.map +1 -0
- package/dist/reportBriefing.js +662 -0
- package/dist/reportBriefing.js.map +1 -0
- package/dist/searchTemplate.d.ts.map +1 -1
- package/dist/searchTemplate.js +65 -53
- package/dist/searchTemplate.js.map +1 -1
- package/dist/services/graphRouter.d.ts +7 -0
- package/dist/services/graphRouter.d.ts.map +1 -0
- package/dist/services/graphRouter.js +7 -0
- package/dist/services/graphRouter.js.map +1 -0
- package/dist/services/notifications.d.ts +49 -0
- package/dist/services/notifications.d.ts.map +1 -0
- package/dist/services/notifications.js +206 -0
- package/dist/services/notifications.js.map +1 -0
- package/dist/sessionTracker.d.ts +19 -2
- package/dist/sessionTracker.d.ts.map +1 -1
- package/dist/sessionTracker.js +69 -16
- package/dist/sessionTracker.js.map +1 -1
- package/dist/skillClient.d.ts.map +1 -1
- package/dist/skillClient.js +11 -6
- package/dist/skillClient.js.map +1 -1
- package/dist/svgVisuals.d.ts +17 -19
- package/dist/svgVisuals.d.ts.map +1 -1
- package/dist/svgVisuals.js +189 -233
- package/dist/svgVisuals.js.map +1 -1
- package/dist/systemPrompt.d.ts +7 -2
- package/dist/systemPrompt.d.ts.map +1 -1
- package/dist/systemPrompt.js +110 -68
- package/dist/systemPrompt.js.map +1 -1
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +15 -0
- package/dist/telemetry.js.map +1 -1
- package/dist/test_adjacent_trends_polymorphic.d.ts +2 -0
- package/dist/test_adjacent_trends_polymorphic.d.ts.map +1 -0
- package/dist/test_adjacent_trends_polymorphic.js +154 -0
- package/dist/test_adjacent_trends_polymorphic.js.map +1 -0
- package/dist/test_book_a_call_live.js +18 -5
- package/dist/test_book_a_call_live.js.map +1 -1
- package/dist/test_byo_mcp_submission_clarity.d.ts +2 -0
- package/dist/test_byo_mcp_submission_clarity.d.ts.map +1 -0
- package/dist/test_byo_mcp_submission_clarity.js +142 -0
- package/dist/test_byo_mcp_submission_clarity.js.map +1 -0
- package/dist/test_capabilities_guidance.d.ts +2 -0
- package/dist/test_capabilities_guidance.d.ts.map +1 -0
- package/dist/test_capabilities_guidance.js +372 -0
- package/dist/test_capabilities_guidance.js.map +1 -0
- package/dist/test_client_provenance.d.ts +2 -0
- package/dist/test_client_provenance.d.ts.map +1 -0
- package/dist/test_client_provenance.js +77 -0
- package/dist/test_client_provenance.js.map +1 -0
- package/dist/test_connection_surface_cleanup.d.ts +2 -0
- package/dist/test_connection_surface_cleanup.d.ts.map +1 -0
- package/dist/test_connection_surface_cleanup.js +203 -0
- package/dist/test_connection_surface_cleanup.js.map +1 -0
- package/dist/test_consult_routing.d.ts +2 -0
- package/dist/test_consult_routing.d.ts.map +1 -0
- package/dist/test_consult_routing.js +86 -0
- package/dist/test_consult_routing.js.map +1 -0
- package/dist/test_consult_split.d.ts +2 -0
- package/dist/test_consult_split.d.ts.map +1 -0
- package/dist/test_consult_split.js +30 -0
- package/dist/test_consult_split.js.map +1 -0
- package/dist/test_coverage_relevance.js +111 -70
- package/dist/test_coverage_relevance.js.map +1 -1
- package/dist/test_coverage_replay.d.ts +2 -0
- package/dist/test_coverage_replay.d.ts.map +1 -0
- package/dist/test_coverage_replay.js +170 -0
- package/dist/test_coverage_replay.js.map +1 -0
- package/dist/test_dcr_and_legacy_deprecation.js +45 -50
- package/dist/test_dcr_and_legacy_deprecation.js.map +1 -1
- package/dist/test_demand_signal_logging.d.ts +2 -0
- package/dist/test_demand_signal_logging.d.ts.map +1 -0
- package/dist/test_demand_signal_logging.js +92 -0
- package/dist/test_demand_signal_logging.js.map +1 -0
- package/dist/test_earnings_activity_scope.d.ts +5 -0
- package/dist/test_earnings_activity_scope.d.ts.map +1 -0
- package/dist/test_earnings_activity_scope.js +101 -0
- package/dist/test_earnings_activity_scope.js.map +1 -0
- package/dist/test_earnings_divergence_live.d.ts +5 -0
- package/dist/test_earnings_divergence_live.d.ts.map +1 -0
- package/dist/test_earnings_divergence_live.js +135 -0
- package/dist/test_earnings_divergence_live.js.map +1 -0
- package/dist/test_earnings_hygiene_and_binding.d.ts +5 -0
- package/dist/test_earnings_hygiene_and_binding.d.ts.map +1 -0
- package/dist/test_earnings_hygiene_and_binding.js +104 -0
- package/dist/test_earnings_hygiene_and_binding.js.map +1 -0
- package/dist/test_exec_quotes_render.d.ts +2 -0
- package/dist/test_exec_quotes_render.d.ts.map +1 -0
- package/dist/test_exec_quotes_render.js +86 -0
- package/dist/test_exec_quotes_render.js.map +1 -0
- package/dist/test_expert_intro.d.ts +2 -0
- package/dist/test_expert_intro.d.ts.map +1 -0
- package/dist/test_expert_intro.js +57 -0
- package/dist/test_expert_intro.js.map +1 -0
- package/dist/test_expert_layer.d.ts +11 -0
- package/dist/test_expert_layer.d.ts.map +1 -0
- package/dist/test_expert_layer.js +356 -0
- package/dist/test_expert_layer.js.map +1 -0
- package/dist/test_gap_alert.js +8 -0
- package/dist/test_gap_alert.js.map +1 -1
- package/dist/test_grok_offering_surfaces.d.ts +2 -0
- package/dist/test_grok_offering_surfaces.d.ts.map +1 -0
- package/dist/test_grok_offering_surfaces.js +155 -0
- package/dist/test_grok_offering_surfaces.js.map +1 -0
- package/dist/test_human_agent_live.d.ts +2 -0
- package/dist/test_human_agent_live.d.ts.map +1 -0
- package/dist/test_human_agent_live.js +48 -0
- package/dist/test_human_agent_live.js.map +1 -0
- package/dist/test_identity_gap.d.ts +2 -0
- package/dist/test_identity_gap.d.ts.map +1 -0
- package/dist/test_identity_gap.js +171 -0
- package/dist/test_identity_gap.js.map +1 -0
- package/dist/test_intelligence_and_verifier.d.ts +17 -0
- package/dist/test_intelligence_and_verifier.d.ts.map +1 -0
- package/dist/test_intelligence_and_verifier.js +162 -0
- package/dist/test_intelligence_and_verifier.js.map +1 -0
- package/dist/test_latency_mcp_brief5.d.ts +12 -0
- package/dist/test_latency_mcp_brief5.d.ts.map +1 -0
- package/dist/test_latency_mcp_brief5.js +200 -0
- package/dist/test_latency_mcp_brief5.js.map +1 -0
- package/dist/test_limit_and_credit_card_capture.d.ts +21 -0
- package/dist/test_limit_and_credit_card_capture.d.ts.map +1 -0
- package/dist/test_limit_and_credit_card_capture.js +216 -0
- package/dist/test_limit_and_credit_card_capture.js.map +1 -0
- package/dist/test_list_graphs_topics.js +1 -1
- package/dist/test_list_graphs_topics.js.map +1 -1
- package/dist/test_live_deployed_mcp_search.d.ts +2 -0
- package/dist/test_live_deployed_mcp_search.d.ts.map +1 -0
- package/dist/test_live_deployed_mcp_search.js +85 -0
- package/dist/test_live_deployed_mcp_search.js.map +1 -0
- package/dist/test_live_deployed_split.d.ts +2 -0
- package/dist/test_live_deployed_split.d.ts.map +1 -0
- package/dist/test_live_deployed_split.js +72 -0
- package/dist/test_live_deployed_split.js.map +1 -0
- package/dist/test_live_endpoint_runner.js +2 -2
- package/dist/test_live_endpoint_runner.js.map +1 -1
- package/dist/test_live_mcp.js +1 -1
- package/dist/test_live_mcp.js.map +1 -1
- package/dist/test_live_neil_widget.d.ts +2 -0
- package/dist/test_live_neil_widget.d.ts.map +1 -0
- package/dist/test_live_neil_widget.js +84 -0
- package/dist/test_live_neil_widget.js.map +1 -0
- package/dist/test_longpoll_status.d.ts +2 -0
- package/dist/test_longpoll_status.d.ts.map +1 -0
- package/dist/test_longpoll_status.js +117 -0
- package/dist/test_longpoll_status.js.map +1 -0
- package/dist/test_mcp_find_expert_and_vocabulary_routing.d.ts +2 -0
- package/dist/test_mcp_find_expert_and_vocabulary_routing.d.ts.map +1 -0
- package/dist/test_mcp_find_expert_and_vocabulary_routing.js +130 -0
- package/dist/test_mcp_find_expert_and_vocabulary_routing.js.map +1 -0
- package/dist/test_next_moves.js +644 -279
- package/dist/test_next_moves.js.map +1 -1
- package/dist/test_next_moves_transcripts.js +122 -40
- package/dist/test_next_moves_transcripts.js.map +1 -1
- package/dist/test_on_request_caller_identity.d.ts +13 -0
- package/dist/test_on_request_caller_identity.d.ts.map +1 -0
- package/dist/test_on_request_caller_identity.js +131 -0
- package/dist/test_on_request_caller_identity.js.map +1 -0
- package/dist/test_on_request_intercept.d.ts +10 -0
- package/dist/test_on_request_intercept.d.ts.map +1 -0
- package/dist/test_on_request_intercept.js +95 -0
- package/dist/test_on_request_intercept.js.map +1 -0
- package/dist/test_onboarding_consent_and_errors.d.ts +2 -0
- package/dist/test_onboarding_consent_and_errors.d.ts.map +1 -0
- package/dist/test_onboarding_consent_and_errors.js +110 -0
- package/dist/test_onboarding_consent_and_errors.js.map +1 -0
- package/dist/test_onboarding_live_scenarios.d.ts +2 -0
- package/dist/test_onboarding_live_scenarios.d.ts.map +1 -0
- package/dist/test_onboarding_live_scenarios.js +189 -0
- package/dist/test_onboarding_live_scenarios.js.map +1 -0
- package/dist/test_referral_live.d.ts +2 -0
- package/dist/test_referral_live.d.ts.map +1 -0
- package/dist/test_referral_live.js +33 -0
- package/dist/test_referral_live.js.map +1 -0
- package/dist/test_referral_piers.d.ts +2 -0
- package/dist/test_referral_piers.d.ts.map +1 -0
- package/dist/test_referral_piers.js +33 -0
- package/dist/test_referral_piers.js.map +1 -0
- package/dist/test_report_editorial_briefing.d.ts +21 -0
- package/dist/test_report_editorial_briefing.d.ts.map +1 -0
- package/dist/test_report_editorial_briefing.js +356 -0
- package/dist/test_report_editorial_briefing.js.map +1 -0
- package/dist/test_search_graph_quality.d.ts +2 -0
- package/dist/test_search_graph_quality.d.ts.map +1 -0
- package/dist/test_search_graph_quality.js +493 -0
- package/dist/test_search_graph_quality.js.map +1 -0
- package/dist/test_service_to_service_auth.d.ts +2 -0
- package/dist/test_service_to_service_auth.d.ts.map +1 -0
- package/dist/test_service_to_service_auth.js +199 -0
- package/dist/test_service_to_service_auth.js.map +1 -0
- package/dist/test_sources_live.d.ts +2 -0
- package/dist/test_sources_live.d.ts.map +1 -0
- package/dist/test_sources_live.js +30 -0
- package/dist/test_sources_live.js.map +1 -0
- package/dist/test_specialist_and_analyst_tiers.d.ts +2 -0
- package/dist/test_specialist_and_analyst_tiers.d.ts.map +1 -0
- package/dist/test_specialist_and_analyst_tiers.js +155 -0
- package/dist/test_specialist_and_analyst_tiers.js.map +1 -0
- package/dist/test_v2_2_visual_hardening.d.ts +5 -0
- package/dist/test_v2_2_visual_hardening.d.ts.map +1 -0
- package/dist/test_v2_2_visual_hardening.js +333 -0
- package/dist/test_v2_2_visual_hardening.js.map +1 -0
- package/dist/test_verify_deprecate_render_spec.d.ts +2 -0
- package/dist/test_verify_deprecate_render_spec.d.ts.map +1 -0
- package/dist/test_verify_deprecate_render_spec.js +217 -0
- package/dist/test_verify_deprecate_render_spec.js.map +1 -0
- package/dist/test_verify_neil_demo.d.ts +2 -0
- package/dist/test_verify_neil_demo.d.ts.map +1 -0
- package/dist/test_verify_neil_demo.js +149 -0
- package/dist/test_verify_neil_demo.js.map +1 -0
- package/dist/test_waitable_research_and_grounded_links.d.ts +2 -0
- package/dist/test_waitable_research_and_grounded_links.d.ts.map +1 -0
- package/dist/test_waitable_research_and_grounded_links.js +129 -0
- package/dist/test_waitable_research_and_grounded_links.js.map +1 -0
- package/dist/test_widget_guards.d.ts +2 -0
- package/dist/test_widget_guards.d.ts.map +1 -0
- package/dist/test_widget_guards.js +229 -0
- package/dist/test_widget_guards.js.map +1 -0
- package/dist/test_zero_retention_alerts.d.ts +14 -0
- package/dist/test_zero_retention_alerts.d.ts.map +1 -0
- package/dist/test_zero_retention_alerts.js +76 -0
- package/dist/test_zero_retention_alerts.js.map +1 -0
- package/dist/toolHandlers.d.ts +38 -1
- package/dist/toolHandlers.d.ts.map +1 -1
- package/dist/toolHandlers.js +3856 -938
- package/dist/toolHandlers.js.map +1 -1
- package/dist/tools.d.ts +20 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +25 -4
- package/dist/tools.js.map +1 -1
- package/dist/verify_discoverability.d.ts +2 -0
- package/dist/verify_discoverability.d.ts.map +1 -0
- package/dist/verify_discoverability.js +53 -0
- package/dist/verify_discoverability.js.map +1 -0
- package/dist/verify_tools_endpoint.js +16 -3
- package/dist/verify_tools_endpoint.js.map +1 -1
- package/dist/widgetShell.d.ts +2 -2
- package/dist/widgetShell.d.ts.map +1 -1
- package/dist/widgetShell.js +1 -1
- package/dist/widgetShell.js.map +1 -1
- package/package.json +1 -1
- package/server.json +4 -32
- package/dist/oauthRegisterShim.d.ts +0 -13
- package/dist/oauthRegisterShim.d.ts.map +0 -1
- package/dist/oauthRegisterShim.js +0 -83
- package/dist/oauthRegisterShim.js.map +0 -1
package/dist/catalogCache.d.ts
CHANGED
|
@@ -37,6 +37,15 @@ export interface CatalogGraph {
|
|
|
37
37
|
skill_phase?: string;
|
|
38
38
|
skill_tool_name?: string;
|
|
39
39
|
webpage_url?: string | null;
|
|
40
|
+
core_tension?: string | null | undefined;
|
|
41
|
+
matched_human_twin_slug?: string | null | undefined;
|
|
42
|
+
expert_stance_quote?: string | null | undefined;
|
|
43
|
+
cross_graph_signals?: Array<{
|
|
44
|
+
graph_id: string;
|
|
45
|
+
signal_type: 'validates' | 'contrasts';
|
|
46
|
+
connection_summary: string;
|
|
47
|
+
source_case_study?: string | undefined;
|
|
48
|
+
}> | undefined;
|
|
40
49
|
}
|
|
41
50
|
export interface CatalogResponse {
|
|
42
51
|
version: string;
|
|
@@ -44,27 +53,41 @@ export interface CatalogResponse {
|
|
|
44
53
|
graph_count: number;
|
|
45
54
|
graphs: CatalogGraph[];
|
|
46
55
|
}
|
|
56
|
+
export type AgentCategory = 'human_agent' | 'classic_agent' | 'c_suite_agent' | 'synthetic_agent';
|
|
47
57
|
export interface CatalogAnalyst {
|
|
48
58
|
analyst_id: string;
|
|
49
59
|
name: string;
|
|
50
60
|
description: string;
|
|
61
|
+
category?: AgentCategory;
|
|
62
|
+
category_label?: string;
|
|
63
|
+
twin_type?: string;
|
|
51
64
|
type?: string;
|
|
52
65
|
agent_type?: string;
|
|
53
66
|
kind?: string;
|
|
54
67
|
is_digital_twin?: boolean;
|
|
55
68
|
is_human_agent?: boolean;
|
|
69
|
+
is_classic_agent?: boolean;
|
|
70
|
+
is_c_suite_agent?: boolean;
|
|
56
71
|
consult_tool?: string;
|
|
57
72
|
price?: string;
|
|
58
73
|
offerings?: any[];
|
|
59
74
|
status?: string;
|
|
60
75
|
Status?: string;
|
|
76
|
+
expert_in?: string;
|
|
77
|
+
outside_their_lane?: string;
|
|
78
|
+
topics?: string[];
|
|
79
|
+
what_they_offer?: string;
|
|
80
|
+
example_questions?: string[];
|
|
81
|
+
[key: string]: any;
|
|
61
82
|
}
|
|
83
|
+
export declare function stringifyField(f: any): string;
|
|
84
|
+
export declare function normalizeAnalyst(a: any): CatalogAnalyst;
|
|
62
85
|
/**
|
|
63
86
|
* Initialize the catalog cache. Call once at server startup.
|
|
64
87
|
* Fetches immediately, then sets up hourly refresh.
|
|
65
88
|
*/
|
|
66
89
|
export declare function initCatalogCache(): Promise<void>;
|
|
67
|
-
export declare function setCachedCatalogForTesting(catalog: CatalogResponse, analysts?:
|
|
90
|
+
export declare function setCachedCatalogForTesting(catalog: CatalogResponse, analysts?: any[]): void;
|
|
68
91
|
/**
|
|
69
92
|
* Get the cached catalog. Returns null if not yet fetched.
|
|
70
93
|
*/
|
|
@@ -115,6 +138,11 @@ export declare function buildGraphNamingBlock(): string;
|
|
|
115
138
|
* Build a human-friendly display name for a graph.
|
|
116
139
|
*/
|
|
117
140
|
export declare function buildDisplayName(g: CatalogGraph): string;
|
|
141
|
+
/**
|
|
142
|
+
* Clean display names across MCP surfaces.
|
|
143
|
+
* Removes retired suffixes such as "(Classic Digital Twin)", "(Digital Twin)", etc.
|
|
144
|
+
*/
|
|
145
|
+
export declare function cleanDisplayName(name: string | undefined | null): string;
|
|
118
146
|
/**
|
|
119
147
|
* Build the GRAPH TYPES block from catalog data.
|
|
120
148
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalogCache.d.ts","sourceRoot":"","sources":["../src/catalogCache.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,YAAY;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,uBAAuB,EAAE,MAAM,CAAC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B,0BAA0B,CAAC,EAAE,MAAM,EAAE,CAAC;IACtC,4BAA4B,CAAC,EAAE,MAAM,EAAE,CAAC;IACxC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"catalogCache.d.ts","sourceRoot":"","sources":["../src/catalogCache.ts"],"names":[],"mappings":"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"}
|
package/dist/catalogCache.js
CHANGED
|
@@ -7,6 +7,100 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import axios from 'axios';
|
|
9
9
|
import { cacheClear } from './queryCache.js';
|
|
10
|
+
export function stringifyField(f) {
|
|
11
|
+
if (!f)
|
|
12
|
+
return '';
|
|
13
|
+
if (typeof f === 'string')
|
|
14
|
+
return f.trim();
|
|
15
|
+
if (Array.isArray(f)) {
|
|
16
|
+
return f.map(item => {
|
|
17
|
+
if (typeof item === 'string')
|
|
18
|
+
return item;
|
|
19
|
+
if (item && typeof item === 'object') {
|
|
20
|
+
return [item.title, item.name, item.description, item.topic].filter(Boolean).join(' ');
|
|
21
|
+
}
|
|
22
|
+
return '';
|
|
23
|
+
}).filter(Boolean).join('. ').trim();
|
|
24
|
+
}
|
|
25
|
+
if (typeof f === 'object') {
|
|
26
|
+
return [f.title, f.name, f.description, f.topic].filter(Boolean).join(' ').trim();
|
|
27
|
+
}
|
|
28
|
+
return String(f);
|
|
29
|
+
}
|
|
30
|
+
export function normalizeAnalyst(a) {
|
|
31
|
+
const analyst_id = String(a.analyst_id || a.id || a.slug || a.name || '').trim();
|
|
32
|
+
const name = cleanDisplayName(String(a.name || a.analyst_id || a.id || a.slug || '').trim());
|
|
33
|
+
const description = stringifyField(a.description || a.bio || a.lens || a.standpoint || '');
|
|
34
|
+
const expert_in = stringifyField(a.expert_in || a.expertIn || a.topic || '');
|
|
35
|
+
const outside_their_lane = stringifyField(a.outside_their_lane || a.outsideTheirLane || a.blind_spots || a.blindSpots || '');
|
|
36
|
+
const topics = Array.isArray(a.topics) ? a.topics : (typeof a.topics === 'string' ? a.topics.split(',').map((s) => s.trim()) : undefined);
|
|
37
|
+
const rawSubType = (a.graphSubType || a.graph_sub_type || a.subType || a.type || a.kind || a.agent_type || '').toString().trim();
|
|
38
|
+
const cleanId = analyst_id.toLowerCase();
|
|
39
|
+
// ── 4-Tier Agent Classification ──
|
|
40
|
+
// 1. C-Suite Agents: corporate executive personas grounded in SEC/earnings
|
|
41
|
+
const is_c_suite = cleanId === 'brand-cmo' || cleanId === 'brand-ceo' || cleanId === 'brand-cfo' ||
|
|
42
|
+
/brand-(cmo|ceo|cfo)/i.test(cleanId) || /c-suite|executive/i.test(rawSubType);
|
|
43
|
+
// 2. Classic Agents: public-domain historical thinkers providing philosophical lenses
|
|
44
|
+
const is_classic = !is_c_suite && (rawSubType === 'Classic Digital Twin' ||
|
|
45
|
+
/classic digital twin/i.test(rawSubType) ||
|
|
46
|
+
a.is_classic_agent === true ||
|
|
47
|
+
a.category === 'classic_agent');
|
|
48
|
+
// 3. Human Agents: real living industry figures with consented digital twins
|
|
49
|
+
const is_human = !is_c_suite && !is_classic && Boolean(rawSubType === 'Digital Twin' ||
|
|
50
|
+
rawSubType === 'human_agent' ||
|
|
51
|
+
rawSubType === 'human_twin' ||
|
|
52
|
+
rawSubType === 'expert_twin' ||
|
|
53
|
+
a.is_human_agent ||
|
|
54
|
+
a.is_digital_twin ||
|
|
55
|
+
a.isVerifiedRealPerson ||
|
|
56
|
+
a.is_verified_real_person ||
|
|
57
|
+
a.type === 'human_agent' ||
|
|
58
|
+
a.type === 'human_twin' ||
|
|
59
|
+
a.kind === 'human_agent' ||
|
|
60
|
+
a.kind === 'human_twin' ||
|
|
61
|
+
a.agent_type === 'human_agent' ||
|
|
62
|
+
a.agent_type === 'human_twin');
|
|
63
|
+
let category = 'synthetic_agent';
|
|
64
|
+
let category_label = 'Synthetic Agent';
|
|
65
|
+
let twin_type = undefined;
|
|
66
|
+
if (is_human) {
|
|
67
|
+
category = 'human_agent';
|
|
68
|
+
category_label = 'Human Agent';
|
|
69
|
+
twin_type = 'Expert Digital Twin';
|
|
70
|
+
}
|
|
71
|
+
else if (is_classic) {
|
|
72
|
+
category = 'classic_agent';
|
|
73
|
+
category_label = 'Classic Agent';
|
|
74
|
+
twin_type = 'Classic Agent';
|
|
75
|
+
}
|
|
76
|
+
else if (is_c_suite) {
|
|
77
|
+
category = 'c_suite_agent';
|
|
78
|
+
category_label = 'C-Suite Agent';
|
|
79
|
+
}
|
|
80
|
+
const slug = a.expertSlug || a.expert_slug || a.slug || a.analyst_id || (is_human ? a.id : undefined);
|
|
81
|
+
const consult_tool = is_human ? 'consult_human_agent' : 'consult_analyst';
|
|
82
|
+
return {
|
|
83
|
+
...a,
|
|
84
|
+
analyst_id,
|
|
85
|
+
name,
|
|
86
|
+
description,
|
|
87
|
+
category,
|
|
88
|
+
category_label,
|
|
89
|
+
...(twin_type ? { twin_type } : {}),
|
|
90
|
+
type: category,
|
|
91
|
+
is_human_agent: is_human,
|
|
92
|
+
is_classic_agent: is_classic,
|
|
93
|
+
is_c_suite_agent: is_c_suite,
|
|
94
|
+
is_verified_real_person: is_human,
|
|
95
|
+
consult_tool,
|
|
96
|
+
slug: slug ? String(slug).trim() : undefined,
|
|
97
|
+
...(expert_in ? { expert_in } : {}),
|
|
98
|
+
...(outside_their_lane ? { outside_their_lane } : {}),
|
|
99
|
+
...(topics ? { topics } : {}),
|
|
100
|
+
...(a.what_they_offer || a.whatTheyOffer || a.askLine ? { what_they_offer: stringifyField(a.what_they_offer || a.whatTheyOffer || a.askLine) } : {}),
|
|
101
|
+
...(a.example_questions || a.exampleQuestions || a.exampleQueries ? { example_questions: a.example_questions || a.exampleQuestions || a.exampleQueries } : {})
|
|
102
|
+
};
|
|
103
|
+
}
|
|
10
104
|
// ---------------------------------------------------------------------------
|
|
11
105
|
// Cache
|
|
12
106
|
// ---------------------------------------------------------------------------
|
|
@@ -34,18 +128,103 @@ async function fetchCatalog() {
|
|
|
34
128
|
* Fetch the analysts from the API. Requires internal auth.
|
|
35
129
|
*/
|
|
36
130
|
async function fetchAnalysts() {
|
|
37
|
-
const url = `${API_BASE_URL}/v1/analysts`;
|
|
38
|
-
const internalKey = process.env.FODDA_INTERNAL_API_KEY;
|
|
131
|
+
const url = `${API_BASE_URL}/v1/analysts?include=unclaimed`;
|
|
132
|
+
const internalKey = process.env.FODDA_INTERNAL_API_KEY || process.env.FODDA_API_KEY;
|
|
39
133
|
const headers = internalKey ? { 'Authorization': `Bearer ${internalKey}` } : {};
|
|
40
134
|
try {
|
|
41
135
|
const response = await axios.get(url, { headers, timeout: 10000 });
|
|
42
|
-
|
|
136
|
+
const raw = Array.isArray(response.data) ? response.data : (response.data.analysts || []);
|
|
137
|
+
return raw.map(normalizeAnalyst);
|
|
43
138
|
}
|
|
44
139
|
catch (err) {
|
|
45
140
|
console.error(`[catalogCache] Failed to fetch analysts: ${err.message}`);
|
|
46
141
|
return [];
|
|
47
142
|
}
|
|
48
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* Bridges active individual analysts into the searchable graph catalog.
|
|
146
|
+
* Solves the "two-store indexing gap" where an analyst exists in the Analysts table
|
|
147
|
+
* with a backing Neo4j graph, but has no dedicated record in Airtable's Graph List.
|
|
148
|
+
*/
|
|
149
|
+
function bridgeAnalystGraphs(catalog, analysts) {
|
|
150
|
+
if (!catalog?.graphs)
|
|
151
|
+
return catalog;
|
|
152
|
+
const existingIds = new Set(catalog.graphs.map(g => (g.graph_id || '').toLowerCase().trim()));
|
|
153
|
+
const bridged = [...catalog.graphs];
|
|
154
|
+
for (const a of analysts) {
|
|
155
|
+
const id = (a.analyst_id || a.id || '').toLowerCase().trim();
|
|
156
|
+
const status = (a.status || a.Status || '').toLowerCase().trim();
|
|
157
|
+
if (!id || (status && status !== 'active'))
|
|
158
|
+
continue;
|
|
159
|
+
// Skip synthetic C-suite leads that already span all graphs
|
|
160
|
+
if (a.is_c_suite_agent || /brand-(cmo|ceo|cfo|analyst)/i.test(id))
|
|
161
|
+
continue;
|
|
162
|
+
// Determine target graph IDs for this analyst:
|
|
163
|
+
// Check backingGraphs first (e.g. 'postpals-expert-graph', 'sic', '2026-macro-trend-graph')
|
|
164
|
+
const candidateGraphIds = new Set();
|
|
165
|
+
const backingList = Array.isArray(a.backingGraphs) ? a.backingGraphs : [];
|
|
166
|
+
for (const rawBg of backingList) {
|
|
167
|
+
const bg = (rawBg || '').toLowerCase().trim();
|
|
168
|
+
if (bg && bg !== '*' && !existingIds.has(bg)) {
|
|
169
|
+
candidateGraphIds.add(bg);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// If no un-registered backingGraph found, use the analyst ID itself (e.g. 'peter-abraham-bicycles-cycling')
|
|
173
|
+
if (candidateGraphIds.size === 0 && !existingIds.has(id) && !backingList.includes('*')) {
|
|
174
|
+
candidateGraphIds.add(id);
|
|
175
|
+
}
|
|
176
|
+
if (candidateGraphIds.size === 0)
|
|
177
|
+
continue;
|
|
178
|
+
const topics = Array.isArray(a.topics) ? a.topics : [];
|
|
179
|
+
const expertIn = typeof a.expert_in === 'string' ? a.expert_in : '';
|
|
180
|
+
const desc = a.description || a.what_they_offer || expertIn || `${a.name} expert knowledge graph`;
|
|
181
|
+
for (const targetGraphId of candidateGraphIds) {
|
|
182
|
+
bridged.push({
|
|
183
|
+
graph_id: targetGraphId,
|
|
184
|
+
name: a.name,
|
|
185
|
+
description: desc,
|
|
186
|
+
curator: a.name,
|
|
187
|
+
curator_url: '',
|
|
188
|
+
quality_checker_name: '',
|
|
189
|
+
quality_checker_title: '',
|
|
190
|
+
quality_checker_company: '',
|
|
191
|
+
update_frequency: 'Weekly',
|
|
192
|
+
domain: expertIn || 'Specialist Intelligence',
|
|
193
|
+
version: '1.0.0',
|
|
194
|
+
node_types: ['Trend', 'Article'],
|
|
195
|
+
relationship_types: ['HAS_EVIDENCE'],
|
|
196
|
+
graph_type: 'analyst',
|
|
197
|
+
status: 'live',
|
|
198
|
+
trend_count: 5,
|
|
199
|
+
evidence_count: 5,
|
|
200
|
+
last_synced: new Date().toISOString(),
|
|
201
|
+
topics: topics.length > 0 ? topics : [targetGraphId],
|
|
202
|
+
company: a.company || '',
|
|
203
|
+
headline: a.askLine || expertIn || desc,
|
|
204
|
+
subhead: expertIn || '',
|
|
205
|
+
geography: 'Global',
|
|
206
|
+
icon_url: '',
|
|
207
|
+
source_url: '',
|
|
208
|
+
available_as: 'API, MCP',
|
|
209
|
+
is_playground: false,
|
|
210
|
+
last_updated: new Date().toISOString(),
|
|
211
|
+
published_date: null,
|
|
212
|
+
example_queries: Array.isArray(a.example_questions) ? a.example_questions : [],
|
|
213
|
+
portrait_url: a.portrait_url || '',
|
|
214
|
+
core_tension: null,
|
|
215
|
+
matched_human_twin_slug: id,
|
|
216
|
+
expert_stance_quote: null,
|
|
217
|
+
cross_graph_signals: []
|
|
218
|
+
});
|
|
219
|
+
existingIds.add(targetGraphId);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
...catalog,
|
|
224
|
+
graph_count: bridged.length,
|
|
225
|
+
graphs: bridged
|
|
226
|
+
};
|
|
227
|
+
}
|
|
49
228
|
/**
|
|
50
229
|
* Initialize the catalog cache. Call once at server startup.
|
|
51
230
|
* Fetches immediately, then sets up hourly refresh.
|
|
@@ -53,8 +232,9 @@ async function fetchAnalysts() {
|
|
|
53
232
|
export async function initCatalogCache() {
|
|
54
233
|
try {
|
|
55
234
|
cacheClear();
|
|
56
|
-
|
|
235
|
+
const rawCatalog = await fetchCatalog();
|
|
57
236
|
cachedAnalysts = await fetchAnalysts();
|
|
237
|
+
cachedCatalog = bridgeAnalystGraphs(rawCatalog, cachedAnalysts);
|
|
58
238
|
lastFetchedAt = Date.now();
|
|
59
239
|
rebuildSearchIndex();
|
|
60
240
|
console.error(`[catalogCache] Loaded ${cachedCatalog.graph_count} graphs from catalog (search index: ${graphSearchTexts.size} entries)`);
|
|
@@ -68,8 +248,9 @@ export async function initCatalogCache() {
|
|
|
68
248
|
clearInterval(refreshInterval);
|
|
69
249
|
refreshInterval = setInterval(async () => {
|
|
70
250
|
try {
|
|
71
|
-
|
|
251
|
+
const rawCatalog = await fetchCatalog();
|
|
72
252
|
cachedAnalysts = await fetchAnalysts();
|
|
253
|
+
cachedCatalog = bridgeAnalystGraphs(rawCatalog, cachedAnalysts);
|
|
73
254
|
lastFetchedAt = Date.now();
|
|
74
255
|
rebuildSearchIndex();
|
|
75
256
|
console.error(`[catalogCache] Refreshed catalog — ${cachedCatalog.graph_count} graphs (search index rebuilt) and ${cachedAnalysts.length} analysts`);
|
|
@@ -80,9 +261,9 @@ export async function initCatalogCache() {
|
|
|
80
261
|
}, CATALOG_REFRESH_MS);
|
|
81
262
|
}
|
|
82
263
|
export function setCachedCatalogForTesting(catalog, analysts) {
|
|
83
|
-
cachedCatalog = catalog;
|
|
84
264
|
if (analysts)
|
|
85
|
-
cachedAnalysts = analysts;
|
|
265
|
+
cachedAnalysts = analysts.map(normalizeAnalyst);
|
|
266
|
+
cachedCatalog = bridgeAnalystGraphs(catalog, cachedAnalysts);
|
|
86
267
|
lastFetchedAt = Date.now();
|
|
87
268
|
rebuildSearchIndex();
|
|
88
269
|
}
|
|
@@ -192,6 +373,18 @@ export function buildDisplayName(g) {
|
|
|
192
373
|
}
|
|
193
374
|
return g.name;
|
|
194
375
|
}
|
|
376
|
+
/**
|
|
377
|
+
* Clean display names across MCP surfaces.
|
|
378
|
+
* Removes retired suffixes such as "(Classic Digital Twin)", "(Digital Twin)", etc.
|
|
379
|
+
*/
|
|
380
|
+
export function cleanDisplayName(name) {
|
|
381
|
+
if (!name || typeof name !== 'string')
|
|
382
|
+
return '';
|
|
383
|
+
return name
|
|
384
|
+
.replace(/\s*[\(\[]\s*(?:Classic\s+|Expert\s+|Human\s+)?(?:Digital\s+)?Twin\s*[\)\]]/gi, '')
|
|
385
|
+
.replace(/\s*[\(\[]\s*(?:Classic|Human|Synthetic|C-Suite)\s+Agent\s*[\)\]]/gi, '')
|
|
386
|
+
.trim();
|
|
387
|
+
}
|
|
195
388
|
/**
|
|
196
389
|
* Build the GRAPH TYPES block from catalog data.
|
|
197
390
|
*/
|
|
@@ -592,8 +785,30 @@ const QUERY_EXPANSION_MAP = {
|
|
|
592
785
|
// Pet & Animal Care
|
|
593
786
|
pet: ['pet', 'cpg', 'food', 'wellness', 'retail'],
|
|
594
787
|
pets: ['pet', 'cpg', 'food', 'wellness', 'retail'],
|
|
595
|
-
dog: ['pet', 'cpg', 'food', 'wellness'],
|
|
596
|
-
|
|
788
|
+
dog: ['pet', 'cpg', 'food', 'wellness', 'retail'],
|
|
789
|
+
dogs: ['pet', 'cpg', 'food', 'wellness', 'retail'],
|
|
790
|
+
cat: ['pet', 'cpg', 'food', 'wellness', 'retail'],
|
|
791
|
+
cats: ['pet', 'cpg', 'food', 'wellness', 'retail'],
|
|
792
|
+
petfood: ['pet', 'cpg', 'food', 'wellness', 'retail'],
|
|
793
|
+
// Marketing, Experiential & Activations
|
|
794
|
+
activation: ['retail', 'cpg', 'marketing', 'brand', 'experience', 'hospitality', 'culture'],
|
|
795
|
+
activations: ['retail', 'cpg', 'marketing', 'brand', 'experience', 'hospitality', 'culture'],
|
|
796
|
+
experiential: ['retail', 'cpg', 'marketing', 'brand', 'experience', 'hospitality', 'culture', 'design'],
|
|
797
|
+
popup: ['retail', 'cpg', 'fashion', 'experience', 'design'],
|
|
798
|
+
popups: ['retail', 'cpg', 'fashion', 'experience', 'design'],
|
|
799
|
+
sampling: ['cpg', 'retail', 'food', 'beverage', 'beauty', 'experience'],
|
|
800
|
+
sponsorship: ['marketing', 'brand', 'culture', 'retail', 'entertainment'],
|
|
801
|
+
installation: ['retail', 'design', 'art', 'experience', 'culture'],
|
|
802
|
+
flagship: ['retail', 'fashion', 'design', 'experience', 'brand'],
|
|
803
|
+
immersive: ['retail', 'experience', 'design', 'entertainment', 'technology'],
|
|
804
|
+
stunt: ['marketing', 'brand', 'culture', 'retail'],
|
|
805
|
+
showcase: ['retail', 'design', 'experience', 'marketing'],
|
|
806
|
+
marketing: ['retail', 'cpg', 'brand', 'strategy', 'advertising', 'culture'],
|
|
807
|
+
campaign: ['marketing', 'brand', 'advertising', 'retail', 'cpg'],
|
|
808
|
+
advertising: ['marketing', 'brand', 'media', 'retail', 'cpg'],
|
|
809
|
+
promo: ['marketing', 'retail', 'cpg', 'promotion'],
|
|
810
|
+
promotion: ['marketing', 'retail', 'cpg', 'promotion'],
|
|
811
|
+
hospitality: ['hospitality', 'hotel', 'dining', 'food', 'experience', 'leisure', 'culture'],
|
|
597
812
|
// Tech, AI & SaaS
|
|
598
813
|
ai: ['technology', 'ai', 'software', 'enterprise', 'innovation'],
|
|
599
814
|
saas: ['technology', 'software', 'enterprise', 'b2b'],
|
|
@@ -623,12 +838,15 @@ function scoreClauseRelevance(clause, g) {
|
|
|
623
838
|
const searchText = graphSearchTexts.get(g.graph_id) || buildSearchableText(g);
|
|
624
839
|
const topicsText = [...(g.topics || []), ...(g.routing_keywords || []), g.name || '', g.graph_id || ''].join(' ').toLowerCase();
|
|
625
840
|
const domainText = (g.domain || '').toLowerCase();
|
|
841
|
+
const words = new Set(searchText.split(/[^a-z0-9]+/));
|
|
842
|
+
const topicWords = new Set(topicsText.split(/[^a-z0-9]+/));
|
|
843
|
+
const domainWords = new Set(domainText.split(/[^a-z0-9]+/));
|
|
626
844
|
let matchedTerms = 0;
|
|
627
845
|
let highValueMatches = 0;
|
|
628
846
|
for (const term of terms) {
|
|
629
|
-
if (
|
|
847
|
+
if (words.has(term)) {
|
|
630
848
|
matchedTerms++;
|
|
631
|
-
if (
|
|
849
|
+
if (topicWords.has(term) || domainWords.has(term)) {
|
|
632
850
|
highValueMatches++;
|
|
633
851
|
}
|
|
634
852
|
}
|
|
@@ -649,9 +867,9 @@ function scoreClauseRelevance(clause, g) {
|
|
|
649
867
|
let expMatches = 0;
|
|
650
868
|
let expHighValueMatches = 0;
|
|
651
869
|
for (const exp of expandedSet) {
|
|
652
|
-
if (
|
|
870
|
+
if (words.has(exp)) {
|
|
653
871
|
expMatches++;
|
|
654
|
-
if (
|
|
872
|
+
if (topicWords.has(exp) || domainWords.has(exp)) {
|
|
655
873
|
expHighValueMatches++;
|
|
656
874
|
}
|
|
657
875
|
}
|
|
@@ -686,6 +904,18 @@ function scoreClauseRelevance(clause, g) {
|
|
|
686
904
|
finalScore = Math.min(finalScore, 0.40); // Cap generic agency floor
|
|
687
905
|
}
|
|
688
906
|
}
|
|
907
|
+
// Experiential & Activation Tactic Boost
|
|
908
|
+
const experientialTerms = new Set([
|
|
909
|
+
'activation', 'activations', 'experiential', 'popup', 'popups', 'sampling',
|
|
910
|
+
'installation', 'flagship', 'immersive', 'stunt', 'showcase'
|
|
911
|
+
]);
|
|
912
|
+
const queryHasExperiential = terms.some(t => experientialTerms.has(t));
|
|
913
|
+
if (queryHasExperiential) {
|
|
914
|
+
const isExperienceGraph = /retail|cpg|brand|marketing|experience|culture|hospitality/i.test(g.graph_id + ' ' + (g.domain || '') + ' ' + (g.topics || []).join(' ') + ' ' + (g.routing_keywords || []).join(' '));
|
|
915
|
+
if (isExperienceGraph || g.graph_id === 'retail') {
|
|
916
|
+
finalScore += 0.20; // Experiential Format Boost
|
|
917
|
+
}
|
|
918
|
+
}
|
|
689
919
|
// Generalized Narrow-Domain Mismatch Penalty
|
|
690
920
|
const narrowDomains = ['beauty', 'gaming', 'automotive', 'fashion'];
|
|
691
921
|
for (const dom of narrowDomains) {
|
|
@@ -773,9 +1003,30 @@ export function getRelevantGraphs(query, minGraphs = 4, maxGraphs = 15, threshol
|
|
|
773
1003
|
if (skippedShells > 0) {
|
|
774
1004
|
console.error(`[graphRouter] Skipped ${skippedShells} unsynced graph shell(s) (trend_count=0, last_synced=null): ${shellGraphs.map(g => g.graph_id).join(', ')}`);
|
|
775
1005
|
}
|
|
776
|
-
// ── Phase 0: Direct name matching ──
|
|
1006
|
+
// ── Phase 0: Direct name matching & phrase routing overrides ──
|
|
777
1007
|
const queryLower = query.toLowerCase();
|
|
778
1008
|
const directMatchIds = new Set();
|
|
1009
|
+
const isCreatorQuery = /creator economy|content creator|creator monetization|creators report/i.test(queryLower);
|
|
1010
|
+
const isNightlifeQuery = /nightlife|going out|shared experiences|shared social experiences/i.test(queryLower);
|
|
1011
|
+
const eligibleGraphs = syncedGraphs.filter(g => {
|
|
1012
|
+
if (isCreatorQuery && g.graph_id === 'mary-shelley')
|
|
1013
|
+
return false;
|
|
1014
|
+
return true;
|
|
1015
|
+
});
|
|
1016
|
+
if (isCreatorQuery) {
|
|
1017
|
+
for (const g of eligibleGraphs) {
|
|
1018
|
+
if (g.graph_id === 'visa-creators_report-2025' || g.graph_id.includes('youtube') || g.graph_id.includes('tiktok')) {
|
|
1019
|
+
directMatchIds.add(g.graph_id);
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
if (isNightlifeQuery) {
|
|
1024
|
+
for (const g of eligibleGraphs) {
|
|
1025
|
+
if (g.graph_id.includes('bompasparr')) {
|
|
1026
|
+
directMatchIds.add(g.graph_id);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
779
1030
|
const matchesWordBoundary = (text, term) => {
|
|
780
1031
|
if (!term || term.length < 3)
|
|
781
1032
|
return false;
|
|
@@ -790,7 +1041,7 @@ export function getRelevantGraphs(query, minGraphs = 4, maxGraphs = 15, threshol
|
|
|
790
1041
|
const rx = new RegExp(`\\b${escaped}\\b`, 'i');
|
|
791
1042
|
return rx.test(text);
|
|
792
1043
|
};
|
|
793
|
-
for (const g of
|
|
1044
|
+
for (const g of eligibleGraphs) {
|
|
794
1045
|
// Check graph_id (e.g., "alyson-stevens-macro", "sic")
|
|
795
1046
|
if (g.graph_id.length > 3 && matchesWordBoundary(queryLower, g.graph_id)) {
|
|
796
1047
|
directMatchIds.add(g.graph_id);
|
|
@@ -832,7 +1083,7 @@ export function getRelevantGraphs(query, minGraphs = 4, maxGraphs = 15, threshol
|
|
|
832
1083
|
console.error(`[graphRouter] Phase 0 direct name matches: ${[...directMatchIds].join(', ')}`);
|
|
833
1084
|
}
|
|
834
1085
|
// Score ALL graph types together — domain, expert, industry report compete on merit
|
|
835
|
-
const scored =
|
|
1086
|
+
const scored = eligibleGraphs.map(g => {
|
|
836
1087
|
const isDirect = directMatchIds.has(g.graph_id);
|
|
837
1088
|
return {
|
|
838
1089
|
graph: g,
|