@fettstorch/clai 0.1.2 → 0.1.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  # Command Line AI Interface (CLAI)
2
2
 
3
3
  A tool for AI powered web search/scrape and summarization in the Terminal.
4
- Built for fun during a hack/jam in order to learn more about AI and CLIs.
4
+ Built for fun in order to learn more about AI and CLIs.
5
5
 
6
6
  ## Installation
7
7
 
@@ -13,7 +13,7 @@ Install it locally in order to use the clai function in your project.
13
13
  ```bash
14
14
  npm install clai
15
15
  ```
16
- Using both the CLI tool and the clai function requires an OpenAI API key.
16
+ Using both the CLI tool and the clai function requires an OpenAI API key. For the CLI tool make sure to set the `OPENAI_API_KEY` environment variable.
17
17
 
18
18
  ## OpenAI API Key Setup
19
19
 
package/dist/cli.js CHANGED
@@ -67816,7 +67816,10 @@ async function scrape(input) {
67816
67816
  }
67817
67817
  }
67818
67818
  function isValidUrl(input) {
67819
- return !input.includes(" ");
67819
+ if (input.includes(" "))
67820
+ return false;
67821
+ const tldPattern = /^[^\s]+\.[a-z]{2,}$/i;
67822
+ return tldPattern.test(input);
67820
67823
  }
67821
67824
  function normalizeUrl(url) {
67822
67825
  if (!url.startsWith("http://") && !url.startsWith("https://")) {
@@ -67834,6 +67837,8 @@ async function getGoogleResults(query) {
67834
67837
  const urlLower = url.toLowerCase();
67835
67838
  return !urlLower.includes("www.google") && !urlLower.includes("gstatic.com") && !urlLower.includes("googleapis.com") && !urlLower.includes("googleadservices") && queryWords.some((word) => urlLower.includes(word));
67836
67839
  }));
67840
+ console.log("queryWords", queryWords);
67841
+ console.log("filteredUrls", filteredUrls);
67837
67842
  const results = [...filteredUrls].slice(0, 3);
67838
67843
  if (results.length === 0) {
67839
67844
  throw new Error("No search results found");
@@ -72936,10 +72941,11 @@ async function summarizeWebPage(content, openAIApiKey) {
72936
72941
  }
72937
72942
  }
72938
72943
  };
72939
- return openai.completeStructured(prompt2, {
72944
+ const result = await openai.completeStructured(prompt2, {
72940
72945
  temperature: 0.3,
72941
72946
  responseSchema: schema
72942
72947
  });
72948
+ return result;
72943
72949
  }
72944
72950
 
72945
72951
  // src/index.ts
@@ -73012,6 +73018,9 @@ async function animateText(text3, delay = 25) {
73012
73018
  process.stdin.removeListener("keypress", keypressHandler);
73013
73019
  process.stdout.write("\n");
73014
73020
  }
73021
+ function formatMarkdownForTerminal(text3) {
73022
+ return text3.replace(/\*\*(.*?)\*\*/g, (_3, content) => source_default.bold(content));
73023
+ }
73015
73024
  async function analyzeInput(input, openAIKey) {
73016
73025
  const spinner = ora("Analyzing content...").start();
73017
73026
  try {
@@ -73019,7 +73028,8 @@ async function analyzeInput(input, openAIKey) {
73019
73028
  spinner.succeed("Analysis complete");
73020
73029
  console.log(source_default.green.bold(`
73021
73030
  \uD83D\uDCDD Summary:`));
73022
- await animateText(result.summary);
73031
+ const formattedContent = formatMarkdownForTerminal(result.summary);
73032
+ await animateText(formattedContent);
73023
73033
  const { selectedLink } = await esm_default12.prompt([
73024
73034
  {
73025
73035
  type: "list",
package/dist/index.js CHANGED
@@ -41021,7 +41021,10 @@ async function scrape(input) {
41021
41021
  }
41022
41022
  }
41023
41023
  function isValidUrl(input) {
41024
- return !input.includes(" ");
41024
+ if (input.includes(" "))
41025
+ return false;
41026
+ const tldPattern = /^[^\s]+\.[a-z]{2,}$/i;
41027
+ return tldPattern.test(input);
41025
41028
  }
41026
41029
  function normalizeUrl(url) {
41027
41030
  if (!url.startsWith("http://") && !url.startsWith("https://")) {
@@ -41039,6 +41042,8 @@ async function getGoogleResults(query) {
41039
41042
  const urlLower = url.toLowerCase();
41040
41043
  return !urlLower.includes("www.google") && !urlLower.includes("gstatic.com") && !urlLower.includes("googleapis.com") && !urlLower.includes("googleadservices") && queryWords.some((word) => urlLower.includes(word));
41041
41044
  }));
41045
+ console.log("queryWords", queryWords);
41046
+ console.log("filteredUrls", filteredUrls);
41042
41047
  const results = [...filteredUrls].slice(0, 3);
41043
41048
  if (results.length === 0) {
41044
41049
  throw new Error("No search results found");
@@ -46141,10 +46146,11 @@ async function summarizeWebPage(content, openAIApiKey) {
46141
46146
  }
46142
46147
  }
46143
46148
  };
46144
- return openai.completeStructured(prompt, {
46149
+ const result = await openai.completeStructured(prompt, {
46145
46150
  temperature: 0.3,
46146
46151
  responseSchema: schema
46147
46152
  });
46153
+ return result;
46148
46154
  }
46149
46155
 
46150
46156
  // src/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fettstorch/clai",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "main": "dist/index.js",
5
5
  "bin": {
6
6
  "clai": "dist/cli.js"
package/src/cli.ts CHANGED
@@ -87,6 +87,10 @@ async function animateText(text: string, delay = 25) {
87
87
  process.stdout.write('\n');
88
88
  }
89
89
 
90
+ function formatMarkdownForTerminal(text: string): string {
91
+ return text.replace(/\*\*(.*?)\*\*/g, (_, content) => chalk.bold(content));
92
+ }
93
+
90
94
  async function analyzeInput(input: string, openAIKey: string) {
91
95
  const spinner = ora('Analyzing content...').start();
92
96
 
@@ -95,7 +99,8 @@ async function analyzeInput(input: string, openAIKey: string) {
95
99
  spinner.succeed('Analysis complete');
96
100
 
97
101
  console.log(chalk.green.bold('\nšŸ“ Summary:'));
98
- await animateText(result.summary);
102
+ const formattedContent = formatMarkdownForTerminal(result.summary);
103
+ await animateText(formattedContent);
99
104
 
100
105
  // Prompt user to select a link
101
106
  const { selectedLink } = await inquirer.prompt([
package/src/openai.ts CHANGED
@@ -6,7 +6,7 @@ const MAX_INPUT_TOKENS = 10000;
6
6
  function truncateContent(content: string): string {
7
7
  const maxChars = MAX_INPUT_TOKENS * 4;
8
8
  if (content.length <= maxChars) return content;
9
- return content.slice(0, maxChars) + '... (content truncated)';
9
+ return content.slice(0, maxChars);
10
10
  }
11
11
 
12
12
  export interface StructuredResponse<T> {
@@ -53,8 +53,8 @@ class OpenAIWrapper {
53
53
  ): Promise<T> {
54
54
  const truncatedPrompt = truncateContent(prompt);
55
55
  const {
56
- model = 'gpt-3.5-turbo',
57
- temperature = 0.6,
56
+ model = 'gpt-4o-mini',
57
+ temperature = 1.6,
58
58
  functionName = 'generate_response',
59
59
  responseSchema
60
60
  } = options;
package/src/scraper.ts CHANGED
@@ -41,7 +41,12 @@ export async function scrape(input: string): Promise<ScrapedData[]> {
41
41
  // --- module private
42
42
 
43
43
  function isValidUrl(input: string): boolean {
44
- return !input.includes(' ');
44
+ // Check for whitespace
45
+ if (input.includes(' ')) return false;
46
+
47
+ // Check for common TLDs using regex
48
+ const tldPattern = /^[^\s]+\.[a-z]{2,}$/i;
49
+ return tldPattern.test(input);
45
50
  }
46
51
 
47
52
  function normalizeUrl(url: string): string {
@@ -74,6 +79,9 @@ async function getGoogleResults(query: string): Promise<string[]> {
74
79
  })
75
80
  );
76
81
 
82
+ console.log('queryWords', queryWords);
83
+ console.log('filteredUrls', filteredUrls);
84
+
77
85
  const results = [...filteredUrls].slice(0, 3);
78
86
 
79
87
  if (results.length === 0) {
package/src/summarizer.ts CHANGED
@@ -70,8 +70,10 @@ export async function summarizeWebPage(content: string, openAIApiKey: string): P
70
70
  }
71
71
  };
72
72
 
73
- return openai.completeStructured<SummaryResult>(prompt, {
73
+ const result = await openai.completeStructured<SummaryResult>(prompt, {
74
74
  temperature: 0.3,
75
75
  responseSchema: schema
76
76
  });
77
+
78
+ return result;
77
79
  }