@phuetz/code-buddy 0.1.0 → 0.1.1

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 (206) hide show
  1. package/.codebuddy/skills/bundled/brave-search/SKILL.md +490 -0
  2. package/.codebuddy/skills/bundled/exa-search/SKILL.md +1122 -0
  3. package/.codebuddy/skills/bundled/perplexity/SKILL.md +748 -0
  4. package/.codebuddy/skills/bundled/playwright/SKILL.md +520 -0
  5. package/.codebuddy/skills/bundled/puppeteer/SKILL.md +708 -0
  6. package/.codebuddy/skills/bundled/web-fetch/SKILL.md +1003 -0
  7. package/README.md +56 -0
  8. package/dist/agent/agent-state.d.ts +3 -3
  9. package/dist/agent/agent-state.js +6 -6
  10. package/dist/agent/agent-state.js.map +1 -1
  11. package/dist/agent/base-agent.d.ts +4 -4
  12. package/dist/agent/base-agent.js +22 -9
  13. package/dist/agent/base-agent.js.map +1 -1
  14. package/dist/agent/cache-trace.d.ts +56 -0
  15. package/dist/agent/cache-trace.js +98 -0
  16. package/dist/agent/cache-trace.js.map +1 -0
  17. package/dist/agent/codebuddy-agent.js +3 -2
  18. package/dist/agent/codebuddy-agent.js.map +1 -1
  19. package/dist/agent/execution/agent-executor.d.ts +4 -4
  20. package/dist/agent/execution/agent-executor.js +41 -7
  21. package/dist/agent/execution/agent-executor.js.map +1 -1
  22. package/dist/agent/facades/agent-context-facade.js +1 -3
  23. package/dist/agent/facades/agent-context-facade.js.map +1 -1
  24. package/dist/agent/facades/message-history-manager.js +14 -12
  25. package/dist/agent/facades/message-history-manager.js.map +1 -1
  26. package/dist/agent/facades/session-facade.d.ts +3 -3
  27. package/dist/agent/facades/session-facade.js +6 -6
  28. package/dist/agent/facades/session-facade.js.map +1 -1
  29. package/dist/agent/history-repair.d.ts +37 -0
  30. package/dist/agent/history-repair.js +124 -0
  31. package/dist/agent/history-repair.js.map +1 -0
  32. package/dist/agent/specialized/archive-agent.d.ts +3 -0
  33. package/dist/agent/specialized/archive-agent.js +71 -31
  34. package/dist/agent/specialized/archive-agent.js.map +1 -1
  35. package/dist/agent/specialized/security-review/agent.js +19 -8
  36. package/dist/agent/specialized/security-review/agent.js.map +1 -1
  37. package/dist/agent/tool-executor.js +5 -0
  38. package/dist/agent/tool-executor.js.map +1 -1
  39. package/dist/agent/turn-diff-tracker.d.ts +79 -0
  40. package/dist/agent/turn-diff-tracker.js +195 -0
  41. package/dist/agent/turn-diff-tracker.js.map +1 -0
  42. package/dist/checkpoints/checkpoint-versioning.js +78 -20
  43. package/dist/checkpoints/checkpoint-versioning.js.map +1 -1
  44. package/dist/cli/config-loader.js +2 -4
  45. package/dist/cli/config-loader.js.map +1 -1
  46. package/dist/commands/handlers/fcs-handlers.js +1 -1
  47. package/dist/commands/handlers/fcs-handlers.js.map +1 -1
  48. package/dist/commands/handlers/memory-handlers.js +2 -1
  49. package/dist/commands/handlers/memory-handlers.js.map +1 -1
  50. package/dist/commands/handlers/worktree-handlers.js +11 -0
  51. package/dist/commands/handlers/worktree-handlers.js.map +1 -1
  52. package/dist/commands/mcp.d.ts +1 -0
  53. package/dist/commands/mcp.js +66 -7
  54. package/dist/commands/mcp.js.map +1 -1
  55. package/dist/commands/pipeline.js +25 -13
  56. package/dist/commands/pipeline.js.map +1 -1
  57. package/dist/config/model-tools.d.ts +41 -0
  58. package/dist/config/model-tools.js +194 -0
  59. package/dist/config/model-tools.js.map +1 -0
  60. package/dist/context/context-manager-v2.d.ts +2 -1
  61. package/dist/context/context-manager-v2.js +34 -5
  62. package/dist/context/context-manager-v2.js.map +1 -1
  63. package/dist/daemon/daemon-manager.js +23 -19
  64. package/dist/daemon/daemon-manager.js.map +1 -1
  65. package/dist/database/database-manager.d.ts +4 -0
  66. package/dist/database/database-manager.js +16 -7
  67. package/dist/database/database-manager.js.map +1 -1
  68. package/dist/desktop-automation/nutjs-provider.js +89 -0
  69. package/dist/desktop-automation/nutjs-provider.js.map +1 -1
  70. package/dist/fcs/builtins.d.ts +2 -6
  71. package/dist/fcs/builtins.js +2 -568
  72. package/dist/fcs/builtins.js.map +1 -1
  73. package/dist/fcs/codebuddy-bindings.d.ts +3 -43
  74. package/dist/fcs/codebuddy-bindings.js +2 -606
  75. package/dist/fcs/codebuddy-bindings.js.map +1 -1
  76. package/dist/fcs/index.d.ts +2 -27
  77. package/dist/fcs/index.js +2 -53
  78. package/dist/fcs/index.js.map +1 -1
  79. package/dist/fcs/lexer.d.ts +2 -37
  80. package/dist/fcs/lexer.js +2 -459
  81. package/dist/fcs/lexer.js.map +1 -1
  82. package/dist/fcs/parser.d.ts +2 -68
  83. package/dist/fcs/parser.js +2 -893
  84. package/dist/fcs/parser.js.map +1 -1
  85. package/dist/fcs/runtime.d.ts +2 -59
  86. package/dist/fcs/runtime.js +2 -623
  87. package/dist/fcs/runtime.js.map +1 -1
  88. package/dist/fcs/script-registry.d.ts +3 -69
  89. package/dist/fcs/script-registry.js +2 -219
  90. package/dist/fcs/script-registry.js.map +1 -1
  91. package/dist/fcs/sync-bindings.d.ts +3 -101
  92. package/dist/fcs/sync-bindings.js +2 -410
  93. package/dist/fcs/sync-bindings.js.map +1 -1
  94. package/dist/fcs/types.d.ts +2 -285
  95. package/dist/fcs/types.js +2 -103
  96. package/dist/fcs/types.js.map +1 -1
  97. package/dist/hooks/use-input-handler.d.ts +1 -1
  98. package/dist/index.js +5 -2
  99. package/dist/index.js.map +1 -1
  100. package/dist/input/voice-control.js +11 -5
  101. package/dist/input/voice-control.js.map +1 -1
  102. package/dist/integrations/json-rpc/server.js +5 -5
  103. package/dist/integrations/json-rpc/server.js.map +1 -1
  104. package/dist/integrations/mcp/mcp-server.js +1 -1
  105. package/dist/integrations/mcp/mcp-server.js.map +1 -1
  106. package/dist/mcp/client.js +2 -1
  107. package/dist/mcp/client.js.map +1 -1
  108. package/dist/mcp/config.js +89 -5
  109. package/dist/mcp/config.js.map +1 -1
  110. package/dist/mcp/mcp-client.js +65 -14
  111. package/dist/mcp/mcp-client.js.map +1 -1
  112. package/dist/mcp/transports.d.ts +0 -1
  113. package/dist/mcp/transports.js +1 -5
  114. package/dist/mcp/transports.js.map +1 -1
  115. package/dist/mcp/types.d.ts +2 -0
  116. package/dist/persistence/session-lock.d.ts +42 -0
  117. package/dist/persistence/session-lock.js +165 -0
  118. package/dist/persistence/session-lock.js.map +1 -0
  119. package/dist/persistence/session-store.d.ts +18 -3
  120. package/dist/persistence/session-store.js +90 -21
  121. package/dist/persistence/session-store.js.map +1 -1
  122. package/dist/plugins/isolated-plugin-runner.d.ts +6 -0
  123. package/dist/plugins/isolated-plugin-runner.js +19 -1
  124. package/dist/plugins/isolated-plugin-runner.js.map +1 -1
  125. package/dist/providers/local-llm-provider.js +21 -4
  126. package/dist/providers/local-llm-provider.js.map +1 -1
  127. package/dist/sandbox/docker-sandbox.js +7 -4
  128. package/dist/sandbox/docker-sandbox.js.map +1 -1
  129. package/dist/scripting/builtins.d.ts +8 -3
  130. package/dist/scripting/builtins.js +506 -355
  131. package/dist/scripting/builtins.js.map +1 -1
  132. package/dist/scripting/codebuddy-bindings.d.ts +47 -0
  133. package/dist/scripting/codebuddy-bindings.js +487 -0
  134. package/dist/scripting/codebuddy-bindings.js.map +1 -0
  135. package/dist/scripting/index.d.ts +33 -30
  136. package/dist/scripting/index.js +41 -36
  137. package/dist/scripting/index.js.map +1 -1
  138. package/dist/scripting/lexer.d.ts +31 -13
  139. package/dist/scripting/lexer.js +379 -292
  140. package/dist/scripting/lexer.js.map +1 -1
  141. package/dist/scripting/parser.d.ts +63 -44
  142. package/dist/scripting/parser.js +700 -473
  143. package/dist/scripting/parser.js.map +1 -1
  144. package/dist/scripting/runtime.d.ts +55 -24
  145. package/dist/scripting/runtime.js +600 -288
  146. package/dist/scripting/runtime.js.map +1 -1
  147. package/dist/scripting/script-registry.d.ts +54 -0
  148. package/dist/scripting/script-registry.js +202 -0
  149. package/dist/scripting/script-registry.js.map +1 -0
  150. package/dist/scripting/sync-bindings.d.ts +105 -0
  151. package/dist/scripting/sync-bindings.js +353 -0
  152. package/dist/scripting/sync-bindings.js.map +1 -0
  153. package/dist/scripting/types.d.ts +297 -199
  154. package/dist/scripting/types.js +86 -60
  155. package/dist/scripting/types.js.map +1 -1
  156. package/dist/search/usearch-index.js +42 -7
  157. package/dist/search/usearch-index.js.map +1 -1
  158. package/dist/security/bash-parser.d.ts +51 -0
  159. package/dist/security/bash-parser.js +327 -0
  160. package/dist/security/bash-parser.js.map +1 -0
  161. package/dist/security/skill-scanner.d.ts +36 -0
  162. package/dist/security/skill-scanner.js +149 -0
  163. package/dist/security/skill-scanner.js.map +1 -0
  164. package/dist/security/trust-folders.d.ts +1 -0
  165. package/dist/security/trust-folders.js +19 -1
  166. package/dist/security/trust-folders.js.map +1 -1
  167. package/dist/server/websocket/handler.js +15 -5
  168. package/dist/server/websocket/handler.js.map +1 -1
  169. package/dist/skills/eligibility.js +26 -4
  170. package/dist/skills/eligibility.js.map +1 -1
  171. package/dist/tasks/background-tasks.js +5 -1
  172. package/dist/tasks/background-tasks.js.map +1 -1
  173. package/dist/tools/apply-patch.d.ts +55 -0
  174. package/dist/tools/apply-patch.js +273 -0
  175. package/dist/tools/apply-patch.js.map +1 -0
  176. package/dist/tools/registry/bash-tools.js +6 -3
  177. package/dist/tools/registry/bash-tools.js.map +1 -1
  178. package/dist/tools/registry/misc-tools.js +1 -2
  179. package/dist/tools/registry/misc-tools.js.map +1 -1
  180. package/dist/tools/registry/search-tools.js +1 -1
  181. package/dist/tools/registry/search-tools.js.map +1 -1
  182. package/dist/tools/registry/text-editor-tools.js +1 -1
  183. package/dist/tools/registry/text-editor-tools.js.map +1 -1
  184. package/dist/tools/registry/todo-tools.js +37 -5
  185. package/dist/tools/registry/todo-tools.js.map +1 -1
  186. package/dist/tools/registry/tool-registry.js +5 -4
  187. package/dist/tools/registry/tool-registry.js.map +1 -1
  188. package/dist/tools/registry/web-tools.d.ts +1 -1
  189. package/dist/tools/registry/web-tools.js +28 -8
  190. package/dist/tools/registry/web-tools.js.map +1 -1
  191. package/dist/tools/text-editor.d.ts +1 -1
  192. package/dist/tools/text-editor.js +23 -5
  193. package/dist/tools/text-editor.js.map +1 -1
  194. package/dist/tools/web-search.d.ts +52 -37
  195. package/dist/tools/web-search.js +368 -163
  196. package/dist/tools/web-search.js.map +1 -1
  197. package/dist/ui/components/ChatInterface.d.ts +1 -1
  198. package/dist/utils/head-tail-truncation.d.ts +34 -0
  199. package/dist/utils/head-tail-truncation.js +98 -0
  200. package/dist/utils/head-tail-truncation.js.map +1 -0
  201. package/dist/utils/sanitize.d.ts +5 -0
  202. package/dist/utils/sanitize.js +19 -0
  203. package/dist/utils/sanitize.js.map +1 -1
  204. package/dist/utils/settings-manager.js +4 -4
  205. package/dist/utils/settings-manager.js.map +1 -1
  206. package/package.json +3 -1
@@ -0,0 +1,748 @@
1
+ ---
2
+ name: perplexity
3
+ version: 1.0.0
4
+ description: Perplexity AI sonar API for AI-powered search with citations and real-time information
5
+ author: Code Buddy
6
+ tags: search, ai, perplexity, citations, real-time, llm, research, sonar
7
+ env:
8
+ PERPLEXITY_API_KEY: ""
9
+ ---
10
+
11
+ # Perplexity AI
12
+
13
+ Perplexity AI provides an AI-powered search API (Sonar) that combines large language models with real-time web search to deliver accurate, cited answers. Unlike traditional search engines that return links, Perplexity synthesizes information and provides inline citations.
14
+
15
+ ## Direct Control (CLI / API / Scripting)
16
+
17
+ ### API Authentication
18
+
19
+ Perplexity uses OpenAI-compatible API with bearer token authentication. Get your API key at https://www.perplexity.ai/settings/api
20
+
21
+ ### Sonar Search Models
22
+
23
+ - **sonar** - Fast, balanced model for general queries
24
+ - **sonar-pro** - Advanced reasoning with deeper analysis
25
+ - **sonar-reasoning** - Chain-of-thought reasoning for complex queries
26
+
27
+ ### Basic Search Query
28
+
29
+ **cURL Example:**
30
+ ```bash
31
+ curl -s https://api.perplexity.ai/chat/completions \
32
+ -H "Authorization: Bearer ${PERPLEXITY_API_KEY}" \
33
+ -H "Content-Type: application/json" \
34
+ -d '{
35
+ "model": "sonar",
36
+ "messages": [
37
+ {
38
+ "role": "user",
39
+ "content": "What are the latest developments in quantum computing as of 2026?"
40
+ }
41
+ ],
42
+ "temperature": 0.2,
43
+ "max_tokens": 1024,
44
+ "return_citations": true,
45
+ "return_images": false
46
+ }' | jq .
47
+ ```
48
+
49
+ **Node.js Example:**
50
+ ```javascript
51
+ import fetch from 'node-fetch';
52
+
53
+ async function perplexitySearch(query, options = {}) {
54
+ const response = await fetch('https://api.perplexity.ai/chat/completions', {
55
+ method: 'POST',
56
+ headers: {
57
+ 'Authorization': `Bearer ${process.env.PERPLEXITY_API_KEY}`,
58
+ 'Content-Type': 'application/json'
59
+ },
60
+ body: JSON.stringify({
61
+ model: options.model || 'sonar',
62
+ messages: [
63
+ {
64
+ role: 'system',
65
+ content: options.systemPrompt || 'Be precise and concise. Provide sources for claims.'
66
+ },
67
+ {
68
+ role: 'user',
69
+ content: query
70
+ }
71
+ ],
72
+ temperature: options.temperature || 0.2,
73
+ max_tokens: options.maxTokens || 1024,
74
+ return_citations: options.returnCitations !== false,
75
+ return_images: options.returnImages || false,
76
+ search_recency_filter: options.recencyFilter || 'month' // hour, day, week, month, year
77
+ })
78
+ });
79
+
80
+ if (!response.ok) {
81
+ throw new Error(`Perplexity API error: ${response.status} ${response.statusText}`);
82
+ }
83
+
84
+ return await response.json();
85
+ }
86
+
87
+ // Usage
88
+ const result = await perplexitySearch('Explain the latest TypeScript 5.6 features', {
89
+ model: 'sonar',
90
+ recencyFilter: 'month',
91
+ returnCitations: true
92
+ });
93
+
94
+ console.log('Answer:', result.choices[0].message.content);
95
+ console.log('\nCitations:', result.citations);
96
+ ```
97
+
98
+ **Python Example:**
99
+ ```python
100
+ import requests
101
+ import os
102
+
103
+ def perplexity_search(query, model='sonar', recency_filter='month', return_citations=True):
104
+ """
105
+ Query Perplexity AI with search augmentation
106
+ recency_filter: 'hour', 'day', 'week', 'month', 'year'
107
+ """
108
+ response = requests.post(
109
+ 'https://api.perplexity.ai/chat/completions',
110
+ headers={
111
+ 'Authorization': f'Bearer {os.environ["PERPLEXITY_API_KEY"]}',
112
+ 'Content-Type': 'application/json'
113
+ },
114
+ json={
115
+ 'model': model,
116
+ 'messages': [
117
+ {
118
+ 'role': 'user',
119
+ 'content': query
120
+ }
121
+ ],
122
+ 'temperature': 0.2,
123
+ 'max_tokens': 1024,
124
+ 'return_citations': return_citations,
125
+ 'return_images': False,
126
+ 'search_recency_filter': recency_filter
127
+ }
128
+ )
129
+
130
+ response.raise_for_status()
131
+ return response.json()
132
+
133
+ # Usage
134
+ result = perplexity_search(
135
+ 'What are the main differences between Rust and Go for systems programming?',
136
+ model='sonar',
137
+ recency_filter='month'
138
+ )
139
+
140
+ print(result['choices'][0]['message']['content'])
141
+ print('\nSources:')
142
+ for i, citation in enumerate(result.get('citations', []), 1):
143
+ print(f"{i}. {citation}")
144
+ ```
145
+
146
+ ### Multi-Turn Conversations
147
+
148
+ ```javascript
149
+ async function perplexityConversation(messages, options = {}) {
150
+ const formattedMessages = messages.map(msg => ({
151
+ role: msg.role,
152
+ content: msg.content
153
+ }));
154
+
155
+ const response = await fetch('https://api.perplexity.ai/chat/completions', {
156
+ method: 'POST',
157
+ headers: {
158
+ 'Authorization': `Bearer ${process.env.PERPLEXITY_API_KEY}`,
159
+ 'Content-Type': 'application/json'
160
+ },
161
+ body: JSON.stringify({
162
+ model: options.model || 'sonar',
163
+ messages: formattedMessages,
164
+ temperature: 0.3,
165
+ max_tokens: 2048,
166
+ return_citations: true,
167
+ search_recency_filter: 'week'
168
+ })
169
+ });
170
+
171
+ return await response.json();
172
+ }
173
+
174
+ // Usage - Build context across queries
175
+ const conversation = [
176
+ { role: 'user', content: 'What is WebAssembly?' },
177
+ { role: 'assistant', content: 'WebAssembly (Wasm) is a binary instruction format...' },
178
+ { role: 'user', content: 'What languages can compile to it?' }
179
+ ];
180
+
181
+ const result = await perplexityConversation(conversation);
182
+ console.log(result.choices[0].message.content);
183
+ ```
184
+
185
+ ### Streaming Responses
186
+
187
+ ```javascript
188
+ async function perplexityStreamingSearch(query) {
189
+ const response = await fetch('https://api.perplexity.ai/chat/completions', {
190
+ method: 'POST',
191
+ headers: {
192
+ 'Authorization': `Bearer ${process.env.PERPLEXITY_API_KEY}`,
193
+ 'Content-Type': 'application/json'
194
+ },
195
+ body: JSON.stringify({
196
+ model: 'sonar',
197
+ messages: [{ role: 'user', content: query }],
198
+ temperature: 0.2,
199
+ max_tokens: 1024,
200
+ stream: true,
201
+ return_citations: true
202
+ })
203
+ });
204
+
205
+ const reader = response.body.getReader();
206
+ const decoder = new TextDecoder();
207
+ let buffer = '';
208
+
209
+ while (true) {
210
+ const { done, value } = await reader.read();
211
+ if (done) break;
212
+
213
+ buffer += decoder.decode(value, { stream: true });
214
+ const lines = buffer.split('\n');
215
+ buffer = lines.pop() || '';
216
+
217
+ for (const line of lines) {
218
+ if (line.startsWith('data: ') && line !== 'data: [DONE]') {
219
+ const data = JSON.parse(line.slice(6));
220
+ const content = data.choices[0]?.delta?.content;
221
+ if (content) {
222
+ process.stdout.write(content);
223
+ }
224
+ }
225
+ }
226
+ }
227
+ console.log('\n');
228
+ }
229
+
230
+ // Usage
231
+ await perplexityStreamingSearch('Summarize the latest AI safety research papers from 2026');
232
+ ```
233
+
234
+ ### Advanced Search with Domain Filtering
235
+
236
+ ```python
237
+ def perplexity_domain_search(query, domains=None, exclude_domains=None):
238
+ """
239
+ Search with domain filtering
240
+ domains: list of domains to include (e.g., ['github.com', 'stackoverflow.com'])
241
+ exclude_domains: list of domains to exclude
242
+ """
243
+ # Add domain filters to query
244
+ domain_query = query
245
+ if domains:
246
+ domain_query += ' ' + ' OR '.join([f'site:{d}' for d in domains])
247
+ if exclude_domains:
248
+ domain_query += ' ' + ' '.join([f'-site:{d}' for d in exclude_domains])
249
+
250
+ return perplexity_search(domain_query, model='sonar-pro')
251
+
252
+ # Search only official documentation
253
+ result = perplexity_domain_search(
254
+ 'React Server Components tutorial',
255
+ domains=['react.dev', 'nextjs.org'],
256
+ exclude_domains=['medium.com']
257
+ )
258
+
259
+ print(result['choices'][0]['message']['content'])
260
+ ```
261
+
262
+ ### Fact-Checking with Citations
263
+
264
+ ```javascript
265
+ async function factCheckWithPerplexity(claim) {
266
+ const query = `Fact check this claim with recent sources: "${claim}". Provide evidence for or against, with citations.`;
267
+
268
+ const result = await perplexitySearch(query, {
269
+ model: 'sonar-pro',
270
+ recencyFilter: 'month',
271
+ returnCitations: true,
272
+ systemPrompt: 'You are a fact-checker. Analyze claims objectively using recent, credible sources. Clearly state if a claim is true, false, or unverifiable.'
273
+ });
274
+
275
+ const answer = result.choices[0].message.content;
276
+ const citations = result.citations || [];
277
+
278
+ return {
279
+ claim,
280
+ verdict: answer,
281
+ sources: citations,
282
+ timestamp: new Date().toISOString()
283
+ };
284
+ }
285
+
286
+ // Usage
287
+ const check = await factCheckWithPerplexity(
288
+ 'GPT-5 was released in January 2026'
289
+ );
290
+
291
+ console.log('Claim:', check.claim);
292
+ console.log('Verdict:', check.verdict);
293
+ console.log('\nSources:');
294
+ check.sources.forEach((source, i) => {
295
+ console.log(`${i + 1}. ${source}`);
296
+ });
297
+ ```
298
+
299
+ ### Research Synthesis
300
+
301
+ ```python
302
+ import json
303
+
304
+ def research_topic(topic, num_queries=3):
305
+ """
306
+ Multi-angle research with progressive refinement
307
+ """
308
+ queries = [
309
+ f"What is {topic}? Provide a comprehensive overview.",
310
+ f"What are the latest developments in {topic} as of 2026?",
311
+ f"What are the main challenges and future directions for {topic}?"
312
+ ]
313
+
314
+ results = []
315
+ all_citations = set()
316
+
317
+ for query in queries[:num_queries]:
318
+ result = perplexity_search(query, model='sonar-pro', recency_filter='month')
319
+ content = result['choices'][0]['message']['content']
320
+ citations = result.get('citations', [])
321
+
322
+ results.append({
323
+ 'query': query,
324
+ 'answer': content,
325
+ 'citations': citations
326
+ })
327
+
328
+ all_citations.update(citations)
329
+
330
+ # Synthesize findings
331
+ synthesis_query = f"Based on recent information, provide a synthesis of: {topic}. Include key points, recent developments, and future outlook."
332
+ synthesis = perplexity_search(synthesis_query, model='sonar-reasoning')
333
+
334
+ return {
335
+ 'topic': topic,
336
+ 'detailed_research': results,
337
+ 'synthesis': synthesis['choices'][0]['message']['content'],
338
+ 'all_sources': list(all_citations),
339
+ 'source_count': len(all_citations)
340
+ }
341
+
342
+ # Usage
343
+ research = research_topic('neuromorphic computing')
344
+ print(json.dumps(research, indent=2))
345
+ ```
346
+
347
+ ## MCP Server Integration
348
+
349
+ Add to `.codebuddy/mcp.json`:
350
+
351
+ ```json
352
+ {
353
+ "mcpServers": {
354
+ "perplexity": {
355
+ "command": "node",
356
+ "args": [
357
+ "/path/to/perplexity-mcp-server/index.js"
358
+ ],
359
+ "env": {
360
+ "PERPLEXITY_API_KEY": "${PERPLEXITY_API_KEY}"
361
+ }
362
+ }
363
+ }
364
+ }
365
+ ```
366
+
367
+ Alternative using ppl-ai/modelcontextprotocol:
368
+
369
+ ```json
370
+ {
371
+ "mcpServers": {
372
+ "perplexity": {
373
+ "command": "npx",
374
+ "args": [
375
+ "-y",
376
+ "@ppl-ai/mcp-server-perplexity"
377
+ ],
378
+ "env": {
379
+ "PERPLEXITY_API_KEY": "${PERPLEXITY_API_KEY}"
380
+ }
381
+ }
382
+ }
383
+ }
384
+ ```
385
+
386
+ ### Available MCP Tools
387
+
388
+ 1. **perplexity_search**
389
+ - AI-powered search with real-time information
390
+ - Parameters: `query` (string), `model` (string), `recency_filter` (string)
391
+ - Returns: Synthesized answer with inline citations
392
+
393
+ 2. **perplexity_chat**
394
+ - Multi-turn conversation with search augmentation
395
+ - Parameters: `messages` (array), `model` (string)
396
+ - Returns: Contextual response with sources
397
+
398
+ 3. **perplexity_fact_check**
399
+ - Verify claims with recent sources
400
+ - Parameters: `claim` (string), `recency` (string)
401
+ - Returns: Fact-check verdict with evidence
402
+
403
+ Example MCP usage:
404
+ ```
405
+ Ask Code Buddy: "Use perplexity_search to explain quantum error correction with recent sources"
406
+ Ask Code Buddy: "Fact check this claim using perplexity_fact_check: AGI was achieved in 2025"
407
+ ```
408
+
409
+ ## Common Workflows
410
+
411
+ ### 1. Research Paper Summary with Citations
412
+
413
+ **Goal:** Get comprehensive summary of a research topic with verifiable sources
414
+
415
+ ```javascript
416
+ async function researchPaperSummary(topic, year = '2026') {
417
+ // Step 1: Get overview with recent filter
418
+ const overview = await perplexitySearch(
419
+ `Summarize the key research papers on ${topic} published in ${year}`,
420
+ {
421
+ model: 'sonar-pro',
422
+ recencyFilter: 'month',
423
+ returnCitations: true,
424
+ systemPrompt: 'Focus on peer-reviewed research. Include paper titles, authors, and key findings.'
425
+ }
426
+ );
427
+
428
+ const summary = overview.choices[0].message.content;
429
+ const citations = overview.citations || [];
430
+
431
+ // Step 2: Extract methodology insights
432
+ const methods = await perplexitySearch(
433
+ `What methodologies are used in recent ${topic} research?`,
434
+ {
435
+ model: 'sonar',
436
+ recencyFilter: 'month'
437
+ }
438
+ );
439
+
440
+ // Step 3: Identify future directions
441
+ const future = await perplexitySearch(
442
+ `What are the open problems and future research directions in ${topic}?`,
443
+ {
444
+ model: 'sonar-reasoning',
445
+ recencyFilter: 'week'
446
+ }
447
+ );
448
+
449
+ // Step 4: Compile research report
450
+ return {
451
+ topic,
452
+ summary,
453
+ methodologies: methods.choices[0].message.content,
454
+ futureDirections: future.choices[0].message.content,
455
+ sources: citations,
456
+ generatedAt: new Date().toISOString()
457
+ };
458
+ }
459
+
460
+ // Usage
461
+ const report = await researchPaperSummary('federated learning privacy');
462
+ console.log(JSON.stringify(report, null, 2));
463
+ ```
464
+
465
+ ### 2. Real-Time News Monitoring
466
+
467
+ **Goal:** Track breaking news and developments on specific topics
468
+
469
+ ```python
470
+ import time
471
+ from datetime import datetime
472
+
473
+ def monitor_topic_news(topic, check_interval=1800):
474
+ """
475
+ Monitor topic for new developments every 30 minutes
476
+ """
477
+ previous_summary = None
478
+
479
+ while True:
480
+ query = f"What are the latest news and developments about {topic} in the past hour?"
481
+
482
+ result = perplexity_search(
483
+ query,
484
+ model='sonar',
485
+ recency_filter='hour'
486
+ )
487
+
488
+ current_summary = result['choices'][0]['message']['content']
489
+
490
+ # Detect if there's new information
491
+ if current_summary != previous_summary:
492
+ print(f"\n[{datetime.now()}] UPDATE on {topic}:")
493
+ print(current_summary)
494
+ print("\nSources:")
495
+ for citation in result.get('citations', []):
496
+ print(f" - {citation}")
497
+
498
+ previous_summary = current_summary
499
+ else:
500
+ print(f"[{datetime.now()}] No new updates")
501
+
502
+ time.sleep(check_interval)
503
+
504
+ # Monitor AI regulation news
505
+ monitor_topic_news('AI regulation United States', check_interval=1800)
506
+ ```
507
+
508
+ ### 3. Comparative Analysis
509
+
510
+ **Goal:** Compare multiple topics or approaches with AI-synthesized insights
511
+
512
+ ```javascript
513
+ async function compareTopics(topicA, topicB, aspect) {
514
+ // Step 1: Get individual summaries
515
+ const [resultA, resultB] = await Promise.all([
516
+ perplexitySearch(
517
+ `Explain ${topicA} focusing on ${aspect}`,
518
+ { model: 'sonar-pro', recencyFilter: 'month' }
519
+ ),
520
+ perplexitySearch(
521
+ `Explain ${topicB} focusing on ${aspect}`,
522
+ { model: 'sonar-pro', recencyFilter: 'month' }
523
+ )
524
+ ]);
525
+
526
+ // Step 2: Direct comparison
527
+ const comparison = await perplexitySearch(
528
+ `Compare and contrast ${topicA} vs ${topicB} in terms of ${aspect}. Provide a balanced analysis with pros and cons of each.`,
529
+ {
530
+ model: 'sonar-reasoning',
531
+ recencyFilter: 'month',
532
+ returnCitations: true
533
+ }
534
+ );
535
+
536
+ // Step 3: Get expert recommendations
537
+ const recommendation = await perplexitySearch(
538
+ `When should someone choose ${topicA} over ${topicB} for ${aspect}?`,
539
+ { model: 'sonar-pro' }
540
+ );
541
+
542
+ return {
543
+ topicA: {
544
+ description: resultA.choices[0].message.content,
545
+ sources: resultA.citations
546
+ },
547
+ topicB: {
548
+ description: resultB.choices[0].message.content,
549
+ sources: resultB.citations
550
+ },
551
+ comparison: comparison.choices[0].message.content,
552
+ recommendation: recommendation.choices[0].message.content,
553
+ allSources: [
554
+ ...resultA.citations || [],
555
+ ...resultB.citations || [],
556
+ ...comparison.citations || []
557
+ ]
558
+ };
559
+ }
560
+
561
+ // Usage
562
+ const analysis = await compareTopics(
563
+ 'PostgreSQL',
564
+ 'MongoDB',
565
+ 'performance and scalability for high-traffic applications'
566
+ );
567
+
568
+ console.log('=== COMPARISON ANALYSIS ===\n');
569
+ console.log('Topic A:', analysis.topicA.description);
570
+ console.log('\nTopic B:', analysis.topicB.description);
571
+ console.log('\nDirect Comparison:', analysis.comparison);
572
+ console.log('\nRecommendation:', analysis.recommendation);
573
+ ```
574
+
575
+ ### 4. Technical Documentation Explorer
576
+
577
+ **Goal:** Find and synthesize information from official documentation
578
+
579
+ ```python
580
+ def explore_documentation(technology, question):
581
+ """
582
+ Query official docs and synthesize answers
583
+ """
584
+ # Step 1: Identify official documentation domains
585
+ domains_query = f"What are the official documentation sites for {technology}?"
586
+ domains_result = perplexity_search(domains_query, model='sonar')
587
+
588
+ # Step 2: Search within documentation context
589
+ doc_query = f"According to the official {technology} documentation: {question}"
590
+ doc_result = perplexity_search(
591
+ doc_query,
592
+ model='sonar-pro',
593
+ recency_filter='month'
594
+ )
595
+
596
+ # Step 3: Get practical examples
597
+ examples_query = f"Provide code examples for {question} in {technology}"
598
+ examples_result = perplexity_search(examples_query, model='sonar')
599
+
600
+ # Step 4: Find common pitfalls
601
+ pitfalls_query = f"What are common mistakes or pitfalls when {question} in {technology}?"
602
+ pitfalls_result = perplexity_search(pitfalls_query, model='sonar')
603
+
604
+ return {
605
+ 'technology': technology,
606
+ 'question': question,
607
+ 'official_answer': doc_result['choices'][0]['message']['content'],
608
+ 'examples': examples_result['choices'][0]['message']['content'],
609
+ 'pitfalls': pitfalls_result['choices'][0]['message']['content'],
610
+ 'sources': doc_result.get('citations', [])
611
+ }
612
+
613
+ # Usage
614
+ guide = explore_documentation(
615
+ 'Kubernetes',
616
+ 'How do I configure horizontal pod autoscaling?'
617
+ )
618
+
619
+ print(f"Question: {guide['question']}")
620
+ print(f"\nOfficial Answer:\n{guide['official_answer']}")
621
+ print(f"\nExamples:\n{guide['examples']}")
622
+ print(f"\nCommon Pitfalls:\n{guide['pitfalls']}")
623
+ ```
624
+
625
+ ### 5. Market Research and Trend Analysis
626
+
627
+ **Goal:** Analyze market trends and competitive landscape with recent data
628
+
629
+ ```javascript
630
+ async function marketResearch(industry, company, timeframe = 'month') {
631
+ // Step 1: Industry overview
632
+ const industryOverview = await perplexitySearch(
633
+ `Provide an overview of the ${industry} industry in 2026, including market size, growth rate, and key trends`,
634
+ {
635
+ model: 'sonar-pro',
636
+ recencyFilter: timeframe,
637
+ returnCitations: true
638
+ }
639
+ );
640
+
641
+ // Step 2: Competitive analysis
642
+ const competitive = await perplexitySearch(
643
+ `Who are the main competitors of ${company} in the ${industry} space? Compare their market positions.`,
644
+ {
645
+ model: 'sonar-pro',
646
+ recencyFilter: timeframe
647
+ }
648
+ );
649
+
650
+ // Step 3: Recent developments
651
+ const developments = await perplexitySearch(
652
+ `What are the latest developments, product launches, or strategic moves by ${company} and its competitors?`,
653
+ {
654
+ model: 'sonar',
655
+ recencyFilter: 'week',
656
+ returnCitations: true
657
+ }
658
+ );
659
+
660
+ // Step 4: Future outlook
661
+ const outlook = await perplexitySearch(
662
+ `What is the future outlook for ${company} in the ${industry} market? What are the key opportunities and threats?`,
663
+ {
664
+ model: 'sonar-reasoning',
665
+ recencyFilter: timeframe
666
+ }
667
+ );
668
+
669
+ // Step 5: Compile all sources
670
+ const allCitations = new Set([
671
+ ...industryOverview.citations || [],
672
+ ...developments.citations || []
673
+ ]);
674
+
675
+ return {
676
+ industry,
677
+ company,
678
+ industryAnalysis: industryOverview.choices[0].message.content,
679
+ competitivePosition: competitive.choices[0].message.content,
680
+ recentDevelopments: developments.choices[0].message.content,
681
+ futureOutlook: outlook.choices[0].message.content,
682
+ sources: Array.from(allCitations),
683
+ reportDate: new Date().toISOString()
684
+ };
685
+ }
686
+
687
+ // Usage
688
+ const research = await marketResearch('cloud computing', 'AWS');
689
+ console.log(JSON.stringify(research, null, 2));
690
+
691
+ // Save to file for further analysis
692
+ const fs = require('fs');
693
+ fs.writeFileSync(
694
+ `market-research-${Date.now()}.json`,
695
+ JSON.stringify(research, null, 2)
696
+ );
697
+ ```
698
+
699
+ ## Best Practices
700
+
701
+ 1. **Use Appropriate Models:**
702
+ - `sonar` - Fast queries, general information
703
+ - `sonar-pro` - Complex research, deeper analysis
704
+ - `sonar-reasoning` - Multi-step reasoning, comparisons
705
+
706
+ 2. **Set Recency Filters:** Always specify `search_recency_filter` for time-sensitive queries
707
+
708
+ 3. **Request Citations:** Enable `return_citations: true` for verifiable information
709
+
710
+ 4. **System Prompts:** Use system prompts to guide response style and focus
711
+
712
+ 5. **Temperature Settings:**
713
+ - 0.0-0.3: Factual, deterministic responses
714
+ - 0.4-0.7: Balanced creativity and accuracy
715
+ - 0.8-1.0: Creative, varied responses
716
+
717
+ 6. **Cost Management:**
718
+ - Sonar models are billed per token (input + output)
719
+ - Use shorter queries when possible
720
+ - Cache results for repeated queries
721
+
722
+ 7. **Citation Validation:** Always verify critical information from citations
723
+
724
+ ## Troubleshooting
725
+
726
+ **Invalid API Key:**
727
+ ```bash
728
+ # Test API connectivity
729
+ curl -s https://api.perplexity.ai/chat/completions \
730
+ -H "Authorization: Bearer ${PERPLEXITY_API_KEY}" \
731
+ -H "Content-Type: application/json" \
732
+ -d '{"model":"sonar","messages":[{"role":"user","content":"test"}]}'
733
+ ```
734
+
735
+ **No Citations Returned:**
736
+ - Ensure `return_citations: true` is set
737
+ - Some queries may not have relevant web sources
738
+ - Try more specific queries or adjust recency filter
739
+
740
+ **Rate Limiting:**
741
+ - Implement exponential backoff
742
+ - Cache responses when possible
743
+ - Use batch processing for multiple queries
744
+
745
+ **Inconsistent Results:**
746
+ - Lower temperature for more deterministic output
747
+ - Use sonar-pro for better consistency
748
+ - Provide more context in system prompts