fodda-mcp 1.7.0 → 1.31.0

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 (106) hide show
  1. package/LICENSE +31 -0
  2. package/README.md +184 -24
  3. package/dist/a2aHandler.d.ts +20 -0
  4. package/dist/a2aHandler.d.ts.map +1 -0
  5. package/dist/a2aHandler.js +343 -0
  6. package/dist/a2aHandler.js.map +1 -0
  7. package/dist/agents/fodda-researcher/index.d.ts +38 -0
  8. package/dist/agents/fodda-researcher/index.d.ts.map +1 -0
  9. package/dist/agents/fodda-researcher/index.js +81 -0
  10. package/dist/agents/fodda-researcher/index.js.map +1 -0
  11. package/dist/agents/fodda-researcher/skills.d.ts +16 -0
  12. package/dist/agents/fodda-researcher/skills.d.ts.map +1 -0
  13. package/dist/agents/fodda-researcher/skills.js +163 -0
  14. package/dist/agents/fodda-researcher/skills.js.map +1 -0
  15. package/dist/brandTemplate.d.ts +14 -0
  16. package/dist/brandTemplate.d.ts.map +1 -0
  17. package/dist/brandTemplate.js +742 -0
  18. package/dist/brandTemplate.js.map +1 -0
  19. package/dist/catalogCache.d.ts +207 -0
  20. package/dist/catalogCache.d.ts.map +1 -0
  21. package/dist/catalogCache.js +837 -0
  22. package/dist/catalogCache.js.map +1 -0
  23. package/dist/editorialFill.d.ts +44 -0
  24. package/dist/editorialFill.d.ts.map +1 -0
  25. package/dist/editorialFill.js +377 -0
  26. package/dist/editorialFill.js.map +1 -0
  27. package/dist/enrichment.d.ts +74 -0
  28. package/dist/enrichment.d.ts.map +1 -0
  29. package/dist/enrichment.js +211 -0
  30. package/dist/enrichment.js.map +1 -0
  31. package/dist/errorHandling.d.ts +52 -0
  32. package/dist/errorHandling.d.ts.map +1 -0
  33. package/dist/errorHandling.js +338 -0
  34. package/dist/errorHandling.js.map +1 -0
  35. package/dist/index.d.ts +0 -1
  36. package/dist/index.js +672 -577
  37. package/dist/index.js.map +1 -1
  38. package/dist/pricingCache.d.ts +111 -0
  39. package/dist/pricingCache.d.ts.map +1 -0
  40. package/dist/pricingCache.js +454 -0
  41. package/dist/pricingCache.js.map +1 -0
  42. package/dist/queryCache.d.ts +25 -0
  43. package/dist/queryCache.d.ts.map +1 -0
  44. package/dist/queryCache.js +195 -0
  45. package/dist/queryCache.js.map +1 -0
  46. package/dist/searchTemplate.d.ts +16 -0
  47. package/dist/searchTemplate.d.ts.map +1 -0
  48. package/dist/searchTemplate.js +318 -0
  49. package/dist/searchTemplate.js.map +1 -0
  50. package/dist/sessionTracker.d.ts +39 -0
  51. package/dist/sessionTracker.d.ts.map +1 -0
  52. package/dist/sessionTracker.js +187 -0
  53. package/dist/sessionTracker.js.map +1 -0
  54. package/dist/skillClient.d.ts +142 -0
  55. package/dist/skillClient.d.ts.map +1 -0
  56. package/dist/skillClient.js +256 -0
  57. package/dist/skillClient.js.map +1 -0
  58. package/dist/svgVisuals.d.ts +77 -0
  59. package/dist/svgVisuals.d.ts.map +1 -0
  60. package/dist/svgVisuals.js +323 -0
  61. package/dist/svgVisuals.js.map +1 -0
  62. package/dist/systemPrompt.d.ts +26 -0
  63. package/dist/systemPrompt.d.ts.map +1 -0
  64. package/dist/systemPrompt.js +574 -0
  65. package/dist/systemPrompt.js.map +1 -0
  66. package/dist/test-waverunner-response.d.ts +2 -0
  67. package/dist/test-waverunner-response.d.ts.map +1 -0
  68. package/dist/test-waverunner-response.js +20 -0
  69. package/dist/test-waverunner-response.js.map +1 -0
  70. package/dist/test_analyst.d.ts +2 -0
  71. package/dist/test_analyst.d.ts.map +1 -0
  72. package/dist/test_analyst.js +39 -0
  73. package/dist/test_analyst.js.map +1 -0
  74. package/dist/test_analyst_local.d.ts +2 -0
  75. package/dist/test_analyst_local.d.ts.map +1 -0
  76. package/dist/test_analyst_local.js +51 -0
  77. package/dist/test_analyst_local.js.map +1 -0
  78. package/dist/test_live_mcp.js +1 -1
  79. package/dist/test_skills.d.ts +9 -0
  80. package/dist/test_skills.d.ts.map +1 -0
  81. package/dist/test_skills.js +267 -0
  82. package/dist/test_skills.js.map +1 -0
  83. package/dist/toolHandlers.d.ts +15 -0
  84. package/dist/toolHandlers.d.ts.map +1 -0
  85. package/dist/toolHandlers.js +2986 -0
  86. package/dist/toolHandlers.js.map +1 -0
  87. package/dist/tools.d.ts +78 -3
  88. package/dist/tools.d.ts.map +1 -1
  89. package/dist/tools.js +85 -292
  90. package/dist/tools.js.map +1 -1
  91. package/dist/trialTracker.d.ts +58 -0
  92. package/dist/trialTracker.d.ts.map +1 -0
  93. package/dist/trialTracker.js +179 -0
  94. package/dist/trialTracker.js.map +1 -0
  95. package/dist/types.d.ts +1 -0
  96. package/dist/types.d.ts.map +1 -1
  97. package/dist/verify_hmac.js +1 -1
  98. package/dist/verify_hmac.js.map +1 -1
  99. package/dist/verify_tools_endpoint.js +5 -5
  100. package/dist/verify_tools_endpoint.js.map +1 -1
  101. package/dist/widgetShell.d.ts +15 -0
  102. package/dist/widgetShell.d.ts.map +1 -0
  103. package/dist/widgetShell.js +151 -0
  104. package/dist/widgetShell.js.map +1 -0
  105. package/package.json +8 -4
  106. package/server.json +13 -4
@@ -0,0 +1,343 @@
1
+ /**
2
+ * A2A (Agent-to-Agent) Protocol Handler
3
+ *
4
+ * Implements JSON-RPC 2.0 over HTTP per the A2A v1.0 specification.
5
+ * MVP: Supports `message/send` only — receives a natural language task,
6
+ * routes it through Fodda's existing tool handlers, and returns
7
+ * structured results as A2A Task artifacts.
8
+ *
9
+ * A2A vs MCP:
10
+ * - MCP: client agent calls Fodda tools directly (tool-level granularity)
11
+ * - A2A: client agent delegates a *task* in natural language; Fodda decides
12
+ * which tools to use and returns the synthesized result
13
+ *
14
+ * Spec: https://a2a-protocol.org/latest/specification/
15
+ */
16
+ import crypto from 'crypto';
17
+ import { MCP_SERVER_VERSION } from './tools.js';
18
+ // ---------------------------------------------------------------------------
19
+ // A2A Agent Card — the discovery document agents/registries fetch to learn
20
+ // what Fodda can do. Served at /.well-known/agent-card.json (A2A standard).
21
+ // Skills reflect what the /a2a endpoint can actually fulfil (the classifier's
22
+ // routes), so we never advertise a capability we can't deliver.
23
+ // ---------------------------------------------------------------------------
24
+ const AGENT_CARD = {
25
+ protocolVersion: '0.3.0',
26
+ name: 'Fodda Research Agent',
27
+ description: "Expert-curated trend, brand, research, and earnings intelligence from named experts' knowledge graphs (220+ graphs across retail, beauty, sports, finance, and institutional data). Delegate a task in natural language — Fodda selects the right tools and returns a synthesized result. Pay per task via Stripe Shared Payment Token; no account required.",
28
+ url: 'https://mcp.fodda.ai/a2a',
29
+ preferredTransport: 'JSONRPC',
30
+ version: MCP_SERVER_VERSION,
31
+ provider: { organization: 'Fodda (PSFK)', url: 'https://www.fodda.ai' },
32
+ documentationUrl: 'https://www.fodda.ai/llms.txt',
33
+ iconUrl: 'https://ucarecdn.com/6e7893d7-6b14-426b-83bc-574a3f72d6bc/foddafavicon.png',
34
+ capabilities: { streaming: false, pushNotifications: false, stateTransitionHistory: false },
35
+ defaultInputModes: ['text/plain'],
36
+ defaultOutputModes: ['text/plain', 'application/json'],
37
+ skills: [
38
+ {
39
+ id: 'brand-intelligence',
40
+ name: 'Brand Intelligence',
41
+ description: "Track a brand's trend footprint, competitive context, and market signals across expert-curated graphs.",
42
+ tags: ['brand', 'competitive', 'intelligence'],
43
+ examples: ['What is Nike doing?', 'Brand intelligence for Patagonia'],
44
+ },
45
+ {
46
+ id: 'trend-search',
47
+ name: 'Trend Search',
48
+ description: 'Search expert-curated knowledge graphs for trends with supporting evidence and source attribution.',
49
+ tags: ['trends', 'search', 'research'],
50
+ examples: ['sustainable packaging trends', 'Gen Z beauty habits'],
51
+ },
52
+ {
53
+ id: 'deep-research',
54
+ name: 'Deep Research',
55
+ description: "Synthesize a multi-trend research summary across Fodda's graph network for a topic. Research spans expert graphs, earnings calls, and institutional data.",
56
+ tags: ['research', 'report', 'analysis'],
57
+ examples: ['comprehensive report on Gen Z luxury', 'detailed analysis of the resale market'],
58
+ },
59
+ {
60
+ id: 'earnings-intelligence',
61
+ name: 'Earnings Intelligence',
62
+ description: 'Surface what public companies say on earnings calls — guidance, key topics, and analyst Q&A.',
63
+ tags: ['earnings', 'financial', 'intelligence'],
64
+ examples: ['what are hotel companies saying about labor costs', 'Nike earnings highlights'],
65
+ },
66
+ {
67
+ id: 'expert-consult',
68
+ name: 'Expert Consult',
69
+ description: "Consult a named Human Agent — a real expert's digital twin that answers in their voice and researches across expert graphs, earnings calls, and market data on your behalf.",
70
+ tags: ['expert', 'consult', 'analyst'],
71
+ examples: ['Consult Ben Dietz about culture-led brand strategy', 'Ask Anu Lingala about 2026 macro trends'],
72
+ },
73
+ ],
74
+ };
75
+ function classifyIntent(text) {
76
+ const lower = text.toLowerCase();
77
+ // Expert consult triggers: "Consult Ben Dietz about X", "Ask Anu Lingala: ..."
78
+ const consultMatch = text.match(/^\s*(?:consult|ask)\s+([A-Z][A-Za-z .'-]{2,40}?)\s*(?:about|on|regarding|:)\s+(.+)/i);
79
+ if (consultMatch && consultMatch[1] && consultMatch[2]) {
80
+ return { tool: 'consult', params: { expert_name: consultMatch[1].trim(), query: consultMatch[2].trim() } };
81
+ }
82
+ // Brand-focused queries
83
+ const brandMatch = lower.match(/(?:what is |what's |tell me about |brand (?:intelligence|profile|tracker) (?:for |on )?|track )([a-z][a-z0-9 &'.-]{1,30}?)(?:\s+(?:doing|strategy|innovation|positioning|trends?))?$/i);
84
+ if (brandMatch && brandMatch[1]) {
85
+ return { tool: 'brand_tracker', params: { brand_name: brandMatch[1].trim() } };
86
+ }
87
+ // Explicit brand mentions with "what is X doing" pattern
88
+ const doingMatch = text.match(/what (?:is|are) ([A-Z][A-Za-z0-9 &'.-]{1,30}?) doing/);
89
+ if (doingMatch && doingMatch[1]) {
90
+ return { tool: 'brand_tracker', params: { brand_name: doingMatch[1].trim() } };
91
+ }
92
+ // Deep research triggers
93
+ if (lower.includes('deep research') || lower.includes('comprehensive report') ||
94
+ lower.includes('write me a report') || lower.includes('detailed analysis')) {
95
+ return { tool: 'deep_research', params: { query: text, depth: 'light' } };
96
+ }
97
+ // Earnings triggers
98
+ if (lower.includes('earnings') || lower.includes('q1 ') || lower.includes('q2 ') ||
99
+ lower.includes('q3 ') || lower.includes('q4 ') || lower.match(/what (?:are|did) .+ (?:companies|brands) say/)) {
100
+ return { tool: 'earnings', params: { query: text } };
101
+ }
102
+ // Default: search_graph (the most general tool)
103
+ return { tool: 'search_graph', params: { query: text } };
104
+ }
105
+ async function executeQuery(route, apiKey, userId, foddaRequest) {
106
+ switch (route.tool) {
107
+ case 'search_graph': {
108
+ // Search ALL graphs (no graphId = all-graph parallel search)
109
+ const body = {
110
+ query: route.params.query,
111
+ limit: 10,
112
+ use_semantic: true,
113
+ include_evidence: true,
114
+ };
115
+ const result = await foddaRequest('POST', '/v1/graphs/search', apiKey, userId, body);
116
+ const rows = result?.rows || [];
117
+ if (rows.length === 0) {
118
+ return { text: `No trends found for: "${route.params.query}". Fodda's knowledge graphs may not have coverage on this specific topic.`, data: result };
119
+ }
120
+ // Build a concise markdown summary
121
+ const lines = [];
122
+ lines.push(`## Fodda Trend Intelligence: ${route.params.query}\n`);
123
+ lines.push(`_${rows.length} trends found across Fodda's expert-curated knowledge graphs._\n`);
124
+ for (const row of rows.slice(0, 8)) {
125
+ const score = row.signal_score ? ` (signal: ${row.signal_score})` : '';
126
+ const lifecycle = row.trendLifecycle ? ` · ${row.trendLifecycle}` : '';
127
+ const graph = row.graphName ? ` — _${row.graphName}_` : '';
128
+ lines.push(`### ${row.title || row.trendName}${score}${lifecycle}`);
129
+ if (row.summary || row.description) {
130
+ lines.push((row.summary || row.description).substring(0, 300));
131
+ }
132
+ if (row.evidence && row.evidence.length > 0) {
133
+ lines.push('');
134
+ for (const ev of row.evidence.slice(0, 3)) {
135
+ const link = ev.sourceUrl ? ` — [source](${ev.sourceUrl})` : '';
136
+ lines.push(`- ${(ev.title || ev.snippet || '').substring(0, 150)}${link}`);
137
+ }
138
+ }
139
+ lines.push(`${graph}\n`);
140
+ }
141
+ return { text: lines.join('\n'), data: result };
142
+ }
143
+ case 'brand_tracker': {
144
+ const body = { brand_name: route.params.brand_name };
145
+ const result = await foddaRequest('POST', '/v1/brands/intelligence', apiKey, userId, body);
146
+ const lines = [];
147
+ lines.push(`## Brand Intelligence: ${route.params.brand_name}\n`);
148
+ if (result?.trend_footprint) {
149
+ lines.push(`_Appears in ${result.trend_footprint.length} trends across ${result.cross_graph_presence?.length || 0} knowledge graphs._\n`);
150
+ for (const t of (result.trend_footprint || []).slice(0, 6)) {
151
+ const score = t.signal_score ? ` (signal: ${t.signal_score})` : '';
152
+ lines.push(`- **${t.trend_name}**${score} · ${t.lifecycle || 'unknown'} — ${t.graph_name || ''}`);
153
+ }
154
+ }
155
+ if (result?.competitive_context?.co_occurring?.length > 0) {
156
+ lines.push(`\n### Competitive Context`);
157
+ for (const c of result.competitive_context.co_occurring.slice(0, 5)) {
158
+ lines.push(`- ${c.brand} (${c.pressure_type})`);
159
+ }
160
+ }
161
+ return { text: lines.join('\n') || JSON.stringify(result, null, 2), data: result };
162
+ }
163
+ case 'earnings': {
164
+ const body = { query: route.params.query, limit: 10 };
165
+ const result = await foddaRequest('POST', '/v1/earnings/search', apiKey, userId, body);
166
+ return {
167
+ text: result?.summary || JSON.stringify(result, null, 2),
168
+ data: result,
169
+ };
170
+ }
171
+ case 'consult': {
172
+ // Resolve the free-text expert name against the public analyst roster
173
+ const roster = await foddaRequest('GET', '/v1/analysts', apiKey, userId);
174
+ const analysts = Array.isArray(roster?.analysts) ? roster.analysts
175
+ : Array.isArray(roster) ? roster : [];
176
+ const wanted = route.params.expert_name.toLowerCase();
177
+ const match = analysts.find(a => {
178
+ const name = String(a?.name || '').toLowerCase();
179
+ return name && (name.includes(wanted) || wanted.includes(name));
180
+ });
181
+ if (!match) {
182
+ const names = analysts.map(a => a?.name).filter(Boolean).slice(0, 10).join(', ');
183
+ return { text: `No Fodda expert matched "${route.params.expert_name}". Available experts include: ${names || 'none listed'}.` };
184
+ }
185
+ const result = await foddaRequest('POST', '/v1/analysts/consult', apiKey, userId, {
186
+ analyst_id: match.id,
187
+ query: route.params.query,
188
+ });
189
+ const lines = [];
190
+ lines.push(`## Consulting ${match.name}\n`);
191
+ if (result?.result)
192
+ lines.push(result.result);
193
+ if (Array.isArray(result?.referrals) && result.referrals.length > 0) {
194
+ const refs = result.referrals.map((r) => r?.name).filter(Boolean).join(', ');
195
+ if (refs)
196
+ lines.push(`\n_Also worth checking: ${refs}_`);
197
+ }
198
+ return { text: lines.join('\n') || JSON.stringify(result, null, 2), data: result };
199
+ }
200
+ case 'deep_research': {
201
+ // For A2A MVP, we do a synchronous search (not the async deep_research job)
202
+ // because A2A registries expect a timely response for health probes.
203
+ const body = {
204
+ query: route.params.query,
205
+ limit: 15,
206
+ use_semantic: true,
207
+ include_evidence: true,
208
+ };
209
+ const result = await foddaRequest('POST', '/v1/graphs/search', apiKey, userId, body);
210
+ const rows = result?.rows || [];
211
+ const lines = [];
212
+ lines.push(`## Research Summary: ${route.params.query}\n`);
213
+ lines.push(`_${rows.length} trends analyzed from Fodda's knowledge graph network._\n`);
214
+ for (const row of rows.slice(0, 10)) {
215
+ const score = row.signal_score ? ` (signal: ${row.signal_score})` : '';
216
+ lines.push(`### ${row.title || row.trendName}${score}`);
217
+ if (row.summary || row.description) {
218
+ lines.push((row.summary || row.description).substring(0, 400));
219
+ }
220
+ lines.push('');
221
+ }
222
+ return { text: lines.join('\n'), data: result };
223
+ }
224
+ }
225
+ }
226
+ // ---------------------------------------------------------------------------
227
+ // JSON-RPC helpers
228
+ // ---------------------------------------------------------------------------
229
+ function jsonRpcSuccess(id, result) {
230
+ return { jsonrpc: '2.0', id, result };
231
+ }
232
+ function jsonRpcError(id, code, message, data) {
233
+ return { jsonrpc: '2.0', id, error: { code, message, ...(data ? { data } : {}) } };
234
+ }
235
+ // ---------------------------------------------------------------------------
236
+ // Route registration
237
+ // ---------------------------------------------------------------------------
238
+ export function registerA2ARoute(app, foddaRequest) {
239
+ // ── A2A Agent Card discovery (skills catalog) ──
240
+ const serveAgentCard = (_req, res) => res.json(AGENT_CARD);
241
+ app.get('/.well-known/agent-card.json', serveAgentCard); // A2A current standard
242
+ app.get('/.well-known/agent.json', serveAgentCard); // legacy alias
243
+ app.post('/a2a', async (req, res) => {
244
+ // ── Parse & validate JSON-RPC envelope ──
245
+ const body = req.body;
246
+ if (!body || body.jsonrpc !== '2.0') {
247
+ return res.status(400).json(jsonRpcError(body?.id ?? null, -32600, 'Invalid Request: missing jsonrpc 2.0 field'));
248
+ }
249
+ const requestId = body.id ?? null;
250
+ // ── Method dispatch ──
251
+ switch (body.method) {
252
+ case 'message/send':
253
+ break; // handled below
254
+ // Stubs for future methods — return Method Not Found
255
+ case 'message/stream':
256
+ case 'tasks/get':
257
+ case 'tasks/cancel':
258
+ case 'tasks/list':
259
+ return res.json(jsonRpcError(requestId, -32601, `Method not found: ${body.method}. Only message/send is supported in this version.`));
260
+ default:
261
+ return res.json(jsonRpcError(requestId, -32601, `Method not found: ${body.method}`));
262
+ }
263
+ // ── Extract user text from message parts ──
264
+ const message = body.params?.message;
265
+ if (!message?.parts?.length) {
266
+ return res.json(jsonRpcError(requestId, -32602, 'Invalid params: message.parts is required and must be non-empty'));
267
+ }
268
+ const textPart = message.parts.find(p => p.kind === 'text' && p.text);
269
+ if (!textPart?.text) {
270
+ return res.json(jsonRpcError(requestId, -32602, 'Invalid params: no text part found in message'));
271
+ }
272
+ const queryText = textPart.text;
273
+ // ── Authentication ──
274
+ // Accept: Authorization: Bearer <key>, X-API-Key header, or api_key query param
275
+ const apiKey = (req.headers['authorization']?.toString().replace(/^Bearer\s+/i, ''))
276
+ || req.headers['x-api-key']
277
+ || req.query.api_key
278
+ || '';
279
+ const userId = req.headers['x-user-id']
280
+ || req.query.user_id
281
+ || 'a2a-agent';
282
+ // For unauthenticated requests (health probes), return a minimal valid response
283
+ if (!apiKey) {
284
+ const taskId = `task-${crypto.randomUUID().slice(0, 8)}`;
285
+ const contextId = `ctx-${crypto.randomUUID().slice(0, 8)}`;
286
+ return res.json(jsonRpcSuccess(requestId, {
287
+ id: taskId,
288
+ contextId,
289
+ status: { state: 'completed' },
290
+ artifacts: [{
291
+ name: 'health_check',
292
+ parts: [{
293
+ kind: 'text',
294
+ text: 'Fodda A2A endpoint is operational. Provide an API key via Authorization: Bearer <key> for full access to trend intelligence. Get a key at https://app.fodda.ai',
295
+ }],
296
+ }],
297
+ }));
298
+ }
299
+ // ── Route and execute ──
300
+ try {
301
+ const route = classifyIntent(queryText);
302
+ console.error(`[a2a] message/send: "${queryText.substring(0, 80)}" → ${route.tool}`);
303
+ const result = await executeQuery(route, apiKey, userId, foddaRequest);
304
+ const taskId = `task-${crypto.randomUUID().slice(0, 8)}`;
305
+ const contextId = `ctx-${crypto.randomUUID().slice(0, 8)}`;
306
+ // Build artifacts — always include markdown text, optionally raw JSON
307
+ const artifacts = [
308
+ {
309
+ name: 'research_result',
310
+ description: `Fodda intelligence for: ${queryText.substring(0, 100)}`,
311
+ parts: [{ kind: 'text', text: result.text }],
312
+ },
313
+ ];
314
+ // Include raw data as a structured artifact if the client accepts JSON
315
+ const acceptedOutputs = body.params?.configuration?.acceptedOutputModes || [];
316
+ if (acceptedOutputs.includes('application/json') && result.data) {
317
+ artifacts.push({
318
+ name: 'raw_data',
319
+ description: 'Structured JSON data from Fodda knowledge graphs',
320
+ parts: [{ kind: 'data', data: result.data, mimeType: 'application/json' }],
321
+ });
322
+ }
323
+ return res.json(jsonRpcSuccess(requestId, {
324
+ id: taskId,
325
+ contextId,
326
+ status: { state: 'completed' },
327
+ artifacts,
328
+ }));
329
+ }
330
+ catch (err) {
331
+ const statusCode = err.response?.status;
332
+ const errMsg = err.response?.data?.error?.message || err.message || 'Internal error';
333
+ console.error(`[a2a] Error: ${errMsg}`);
334
+ // Map known error types to appropriate JSON-RPC error codes
335
+ if (statusCode === 401 || statusCode === 403) {
336
+ return res.json(jsonRpcError(requestId, -32001, `Unauthorized: ${errMsg}`));
337
+ }
338
+ return res.json(jsonRpcError(requestId, -32603, `Fodda query failed: ${errMsg}`));
339
+ }
340
+ });
341
+ console.error('[a2a] A2A endpoint registered at POST /a2a (+ agent card at /.well-known/agent-card.json)');
342
+ }
343
+ //# sourceMappingURL=a2aHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a2aHandler.js","sourceRoot":"","sources":["../src/a2aHandler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Fodda Research Agent — System Instruction Builder
3
+ *
4
+ * Loads the 5 skill files and assembles a system instruction for the
5
+ * Gemini Interactions API. This is the "agent" — a skill-injected system
6
+ * prompt that tells Gemini how to conduct Fodda-style research.
7
+ *
8
+ * Usage:
9
+ * import { buildResearcherInstruction } from './agents/fodda-researcher/index.js';
10
+ * const systemInstruction = buildResearcherInstruction(query, graphContext);
11
+ */
12
+ /**
13
+ * Context about pre-fetched Fodda graph results, injected into the
14
+ * system instruction so the agent can reference existing knowledge.
15
+ */
16
+ export interface GraphContext {
17
+ /** Pre-fetched trends from Fodda graphs, stringified JSON */
18
+ graphResults?: string;
19
+ /** Which graphs were searched */
20
+ graphsSearched?: string[];
21
+ /** Total trends found across all graphs */
22
+ totalTrends?: number;
23
+ /** Total evidence pieces collected */
24
+ totalEvidence?: number;
25
+ /** Optional specific graph to focus on (undefined = search all) */
26
+ focusGraphId?: string | undefined;
27
+ /** Pre-fetched earnings-call intelligence (stringified JSON), present when
28
+ * the source router flagged a public company / sector / earnings angle */
29
+ earningsResults?: string;
30
+ }
31
+ /**
32
+ * Build the complete system instruction for the Fodda Research Agent.
33
+ *
34
+ * Concatenates all 5 skill files with a mission preamble and any
35
+ * graph context that was pre-fetched from Fodda's knowledge graphs.
36
+ */
37
+ export declare function buildResearcherInstruction(query: string, context?: GraphContext): string;
38
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agents/fodda-researcher/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH;;;GAGG;AACH,MAAM,WAAW,YAAY;IACzB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC;+EAC2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACtC,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,YAAY,GACvB,MAAM,CAkER"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Fodda Research Agent — System Instruction Builder
3
+ *
4
+ * Loads the 5 skill files and assembles a system instruction for the
5
+ * Gemini Interactions API. This is the "agent" — a skill-injected system
6
+ * prompt that tells Gemini how to conduct Fodda-style research.
7
+ *
8
+ * Usage:
9
+ * import { buildResearcherInstruction } from './agents/fodda-researcher/index.js';
10
+ * const systemInstruction = buildResearcherInstruction(query, graphContext);
11
+ */
12
+ import { SKILL_RESEARCH_METHODOLOGY, SKILL_EVIDENCE_CATEGORIES, SKILL_OUTPUT_FORMAT, SKILL_GRAPH_AWARENESS, SKILL_SOURCE_QUALITY, } from './skills.js';
13
+ /**
14
+ * Build the complete system instruction for the Fodda Research Agent.
15
+ *
16
+ * Concatenates all 5 skill files with a mission preamble and any
17
+ * graph context that was pre-fetched from Fodda's knowledge graphs.
18
+ */
19
+ export function buildResearcherInstruction(query, context) {
20
+ const sections = [];
21
+ // ── Mission preamble ──
22
+ sections.push(`You are the Fodda Research Agent — an autonomous deep researcher that produces
23
+ editorial-quality intelligence reports by combining curated knowledge graph data
24
+ with web research.
25
+
26
+ Your research query is: "${query}"
27
+ ${context?.focusGraphId ? `\nFocus graph: ${context.focusGraphId}` : 'Search all accessible knowledge graphs.'}
28
+
29
+ Follow the skills below precisely. They encode Fodda's research methodology,
30
+ evidence standards, output format, graph attribution rules, and source quality
31
+ requirements.
32
+
33
+ ---`);
34
+ // ── Skills ──
35
+ sections.push(SKILL_RESEARCH_METHODOLOGY);
36
+ sections.push('---');
37
+ sections.push(SKILL_EVIDENCE_CATEGORIES);
38
+ sections.push('---');
39
+ sections.push(SKILL_OUTPUT_FORMAT);
40
+ sections.push('---');
41
+ sections.push(SKILL_GRAPH_AWARENESS);
42
+ sections.push('---');
43
+ sections.push(SKILL_SOURCE_QUALITY);
44
+ // ── Pre-fetched graph context ──
45
+ if (context?.graphResults) {
46
+ sections.push('---');
47
+ sections.push(`# Pre-Loaded Knowledge Graph Data
48
+
49
+ The following trends and evidence were pre-fetched from Fodda's knowledge graphs.
50
+ Use this as your PRIMARY source material. Supplement with Google Search only for
51
+ themes not covered here.
52
+
53
+ Graphs searched: ${context.graphsSearched?.join(', ') || 'unknown'}
54
+ Total trends found: ${context.totalTrends ?? 'unknown'}
55
+ Total evidence pieces: ${context.totalEvidence ?? 'unknown'}
56
+
57
+ ## Graph Data
58
+ ${context.graphResults}`);
59
+ }
60
+ // ── Pre-fetched earnings-call intelligence ──
61
+ if (context?.earningsResults) {
62
+ sections.push('---');
63
+ sections.push(`# Pre-Loaded Earnings Call Intelligence
64
+
65
+ The following earnings-call evidence was pre-fetched because the query involves a
66
+ public company, sector, or earnings-shaped question. Treat it as primary source
67
+ material alongside the graph data.
68
+
69
+ Attribution rule: attribute earnings findings by source TYPE, naming the company
70
+ and period — e.g. "per Ulta's Q1 earnings call…" or "per management commentary on
71
+ Marriott's latest earnings call…". Never attribute earnings data to a knowledge
72
+ graph, and never cite it as generic web research. The same source-type attribution
73
+ applies to any supplemental/institutional data ("per FRED consumer confidence
74
+ data…").
75
+
76
+ ## Earnings Data
77
+ ${context.earningsResults}`);
78
+ }
79
+ return sections.join('\n\n');
80
+ }
81
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/agents/fodda-researcher/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACH,0BAA0B,EAC1B,yBAAyB,EACzB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,GACvB,MAAM,aAAa,CAAC;AAsBrB;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CACtC,KAAa,EACb,OAAsB;IAEtB,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,yBAAyB;IACzB,QAAQ,CAAC,IAAI,CAAC;;;;2BAIS,KAAK;EAC9B,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,kBAAkB,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,yCAAyC;;;;;;IAM1G,CAAC,CAAC;IAEF,eAAe;IACf,QAAQ,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAC1C,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACzC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACnC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACrC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,QAAQ,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;IAEpC,kCAAkC;IAClC,IAAI,OAAO,EAAE,YAAY,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC;;;;;;mBAMH,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS;sBAC5C,OAAO,CAAC,WAAW,IAAI,SAAS;yBAC7B,OAAO,CAAC,aAAa,IAAI,SAAS;;;EAGzD,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACtB,CAAC;IAED,+CAA+C;IAC/C,IAAI,OAAO,EAAE,eAAe,EAAE,CAAC;QAC3B,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC;;;;;;;;;;;;;;EAcpB,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IACzB,CAAC;IAED,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Fodda Research Agent — Skill Definitions
3
+ *
4
+ * These are static skill instruction files that encode the Fodda research
5
+ * methodology. The agent's system instruction is assembled from these skills
6
+ * at runtime.
7
+ * Converted to NLSpec v2 format.
8
+ *
9
+ * To modify a skill, edit the constant below and redeploy.
10
+ */
11
+ export declare const SKILL_RESEARCH_METHODOLOGY = "---\nid: FODDA-SKILL-METHODOLOGY-001\ntitle: Fodda Research Methodology Skill\nversion: 2.0.0\ncompliance: RFC-2119\n---\n\n### SEQUENCE: DeepResearch\n1. **Phase 1: PLAN** \u2014 seconds:\n - Decompose the query into 2-4 research dimensions.\n - Identify which knowledge graph verticals are most relevant.\n - Determine if supplemental data sources (Google Trends, BLS, Census, OECD) are needed.\n - Estimate research depth: light (3-4 sources) vs comprehensive (6+ sources).\n2. **Phase 2: SEARCH** \u2014 primary:\n - Analyze pre-loaded Fodda knowledge graph results.\n - Identify convergence patterns across multiple graphs.\n - Track which graphs yielded strong results and which were sparse.\n - Note signal_score values: 80+ is strong, 60-79 is moderate, below 60 is weak.\n3. **Phase 3: READ** \u2014 deepen:\n - Examine evidence snippets and source URLs for key themes.\n - Use Google Search to find additional context for high-signal trends.\n - Use URL Context for primary source verification if external URLs are referenced.\n - Flag conflicting evidence explicitly.\n4. **Phase 4: SYNTHESIZE** \u2014 connect:\n - Identify the 3-5 strongest themes.\n - Rank by signal strength, evidence count, recency, and cross-graph convergence.\n - Build narrative arc: What is happening -> Why it matters -> What comes next.\n - Note gaps in coverage.\n5. **Phase 5: CITE** \u2014 attribute:\n - Every claim MUST reference its source graph and evidence.\n - Attribute findings to source graph by name.\n - Include source URLs as inline citations.\n - Suggest 2-3 follow-up research questions.\n";
12
+ export declare const SKILL_EVIDENCE_CATEGORIES = "---\nid: FODDA-SKILL-EVIDENCE-001\ntitle: Fodda Evidence Categories Skill\nversion: 2.0.0\ncompliance: RFC-2119\n---\n\n### TOKEN: EvidenceCategories\n\n| Category | What it covers | When to use |\n|----------|---------------|-------------|\n| Case Study | Innovation, strategic moves, novel approaches | Must demonstrate innovation or strategic intent \u2014 NOT routine news |\n| Statistic | Quantitative data \u2014 market sizes, growth rates, survey results | Numbers with clear methodology |\n| Data Point | Factual brand/industry news without innovation | Routine business activity, personnel changes, earnings, regulatory |\n| Analysis | Expert interpretation, industry reports, competitive assessments | Qualitative expert judgment |\n| Interview | Direct quotes from practitioners, executives, researchers | Verbatim attributed speech |\n\n### RULE: EvidenceClassification\n- Case Study REQUIRES demonstrated innovation or strategic intent.\n- Routine brand news (store openings, executive hires) MUST map to Data Point.\n- If an article contains both a stat and analysis, classify by PRIMARY value.\n- \"Report\" MUST map to Analysis.\n- The agent MUST NOT invent a 6th category; all evidence must fit into these 5.\n- A finding MAY cite multiple evidence pieces of different types.\n";
13
+ export declare const SKILL_OUTPUT_FORMAT = "---\nid: FODDA-SKILL-OUTPUT-001\ntitle: Fodda Output Format Skill\nversion: 2.0.0\ncompliance: RFC-2119\n---\n\n### RECORD: ResearchReport\n- executive_summary: String \u2014 2-3 sentences. The single most important finding, stated as a provocative editorial claim.\n- thematic_sections: List[ThematicSection] \u2014 3-5 thematic narrative sections.\n- strategic_agenda: List[Implication] \u2014 2-3 concrete moves.\n- source_landscape: List[SourceLink] \u2014 bulleted list of all source URLs referenced.\n\n### RULE: OutputFormat\n- Thematic sections MUST:\n - Open with a declarative statement.\n - Use flowing paragraphs with embedded data points (no bullet lists).\n - Weave in source citations inline: \"Sephora's AI Color Match drove a 28% conversion lift (PSFK Retail Graph)\".\n - Close with a practical implication: what this means for the practitioner.\n- Tone MUST read like a senior strategist briefing a CMO, not a consultant deck. Strongest findings first.\n- The agent MUST NOT use italicized terms followed by parenthetical attribution for trends. Instead, weave attribution into the narrative sentence as the subject (e.g. \"One trend, [Trend Name] from [Graph/Expert], highlights how...\").\n- Ground every trend in a named example ONLY IF one is provided in the graph evidence. Do NOT hunt via Google Search for missing examples.\n- If a trend lacks recent statistics, the agent SHOULD use the google_search tool to find recent (2025-2026) statistics.\n- Prefer Fodda graph stats over web stats. Cite Fodda stats as: \"According to research tracked in the [Graph/Expert Name] graph...\".\n";
14
+ export declare const SKILL_GRAPH_AWARENESS = "---\nid: FODDA-SKILL-AWARENESS-001\ntitle: Fodda Graph Awareness Skill\nversion: 2.0.0\ncompliance: RFC-2119\n---\n\n### RULE: GraphAwareness\n- Each graph is a curated knowledge graph representing an editorial viewpoint with evidence, not a generic database.\n- Multi-graph convergence (same theme in 2+ graphs) indicates a high-confidence finding.\n- Contradicting graphs MUST be noted explicitly as a tension.\n- Match expert graph terminology on concepts, not labels.\n- Industry report graphs are deep but narrow; excellent for specific verticals.\n\n### TOKEN: GraphTypes\n- PSFK curated graphs: retail, beauty, fashion, sports, sic, ce-design, pew.\n- Expert graphs: individual specialist perspectives (e.g., ezra-eeman-wayfinder, alyson-stevens-macro).\n- Industry report graphs: single-report deep dives (e.g., pwc/sxsw-2026-key-insights, delta/the-connection-index).\n\n### RULE: GraphAttribution\n- The agent MUST NEVER say \"the Fodda graph\" or \"according to Fodda\". Fodda is the platform; graphs are created by named experts.\n- Format: \"According to PSFK's Retail Graph...\" or \"Ezra Eeman's Wayfinder Graph identifies...\".\n- Include graph_id for programmatic reference.\n";
15
+ export declare const SKILL_SOURCE_QUALITY = "---\nid: FODDA-SKILL-QUALITY-001\ntitle: Fodda Source Quality Skill\nversion: 2.0.0\ncompliance: RFC-2119\n---\n\n### TOKEN: SourceCredibilityTiers\n- Tier 5 (Primary Research): Earnings reports, PubMed, OECD, Census, BLS, government filings.\n- Tier 4 (Expert Analysis): PSFK original research, McKinsey, Deloitte, named expert graphs.\n- Tier 3 (Quality Journalism): Financial Times, Bloomberg, Business of Fashion, Wired.\n- Tier 2 (Industry Sources): Trade publications, brand press releases, industry blogs.\n- Tier 1 (Unverified): Social media posts, individual opinions, unattributed claims.\n\n### RULE: SourcePreferenceHierarchy\n- The agent MUST follow this preference order:\n 1. Fodda knowledge graph evidence (pre-vetted, always prefer).\n 2. Supplemental structured data (BLS, Census, Google Trends, OECD).\n 3. Google Search results (web-sourced context for themes not covered).\n 4. URL-fetched primary sources (for deep verification).\n\n### RULE: SourceQualityGate\n- At least 60% of cited evidence SHOULD be tier 3 or above.\n- The agent MUST NOT present a tier 1-2 source without qualification (\"industry reports suggest...\").\n- Acknowledge explicitly if a finding relies on a single source.\n- Recency: Prefer evidence less than 12 months old.\n- Note geographic concentration (e.g., US-only).\n- Trust the graph over web sources in case of conflicts.\n";
16
+ //# sourceMappingURL=skills.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../../src/agents/fodda-researcher/skills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,eAAO,MAAM,0BAA0B,wmDAiCtC,CAAC;AAMF,eAAO,MAAM,yBAAyB,mxCAwBrC,CAAC;AAMF,eAAO,MAAM,mBAAmB,klDAwB/B,CAAC;AAMF,eAAO,MAAM,qBAAqB,8qCAuBjC,CAAC;AAMF,eAAO,MAAM,oBAAoB,02CA4BhC,CAAC"}