├── ChatSH.ts ├── ChatSH_prompt.txt ├── GenAI.md ├── GenAI.ts ├── GenAI_Demo.ts ├── HoleFill.ts ├── README.md ├── RepoManager.md ├── RepoManager.ts ├── RepoManager_Demo.ts ├── Vendors ├── Anthropic.ts ├── Gemini.ts ├── Grok.ts └── OpenAI.ts ├── issue ├── Parse.hs ├── README.md ├── Type.hs └── dump.txt ├── package-lock.json ├── package.json └── tsconfig.json /ChatSH.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bun 2 | 3 | import * as fs from 'fs'; 4 | import * as os from 'os'; 5 | import * as path from 'path'; 6 | import * as readline from 'readline'; 7 | import { Command } from 'commander'; 8 | import { GenAI, tokenCount, MODELS } from './GenAI'; 9 | import { RepoManager } from './RepoManager'; 10 | import { exec } from 'child_process'; 11 | import { promisify } from 'util'; 12 | 13 | const execAsync = promisify(exec); 14 | 15 | /** 16 | * Escapes special characters in a string for use in a regular expression. 17 | * @param string The string to escape. 18 | * @returns The escaped string. 19 | */ 20 | function escapeRegex(string: string): string { 21 | return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); 22 | } 23 | 24 | /** 25 | * Executes a shell command and returns its output or an error message. 26 | * @param script The shell script to execute. 27 | * @returns The command output or error message. 28 | */ 29 | async function executeCommand(script: string): Promise { 30 | try { 31 | const { stdout, stderr } = await execAsync(script); 32 | return stdout + stderr; 33 | } catch (error) { 34 | return (error as Error).message; 35 | } 36 | } 37 | 38 | /** 39 | * Generates the system prompt for the AI, including context management instructions only if files are loaded. 40 | * @param repo The repository manager instance. 41 | * @param shownChunks Record of chunks to show or hide. 42 | * @returns The formatted system prompt. 43 | */ 44 | function getSystemPrompt(repo: RepoManager, shownChunks: Record): string { 45 | const basePrompt = ` 46 | This conversation is running inside a terminal session, on ${os.platform()} ${os.release()}. 47 | 48 | To better assist the user, you can run bash commands on this computer. 49 | 50 | To run a bash command, include a script in your answer, inside tags: 51 | 52 | 53 | shell_script_here 54 | 55 | 56 | For example, to create a file, you can write: 57 | 58 | 59 | cat > hello.ts << EOL 60 | console.log("Hello, world!") 61 | EOL 62 | 63 | 64 | And to run it, you can write: 65 | 66 | 67 | bun hello.ts 68 | 69 | 70 | I will show you the outputs of every command you run. 71 | 72 | Note: only include bash commands when explicitly asked. Example: 73 | - "save a demo JS file": use a RUN command to save it to disk 74 | - "show a demo JS function": use normal code blocks, no RUN 75 | - "what colors apples have?": just answer conversationally 76 | 77 | IMPORTANT: Be CONCISE and DIRECT in your answers. 78 | Do not add any information beyond what has been explicitly asked. 79 | `.trim(); 80 | 81 | const workContext = repo.view( 82 | Object.fromEntries( 83 | Object.entries(shownChunks).filter(([_, value]) => value === true) 84 | ) as Record 85 | ); 86 | 87 | if (workContext.trim() === '') { 88 | return basePrompt; 89 | } 90 | 91 | const contextInstructions = ` 92 | Below is a context of the files I'm working on. 93 | 94 | You can issue the following context management commands: 95 | 96 | - : Expands a chunk. 97 | - : Shortens a chunk. 98 | - : Removes a chunk. 99 | - new_content: Replaces a chunk's contents. 100 | 101 | Include these commands anywhere in your answer to manage your context. 102 | 103 | For example, to show chunk id 000005000000, write: 104 | 105 | 106 | 107 | The work context is: 108 | 109 | ${workContext} 110 | 111 | Notes: 112 | - Chunks are labelled with a 12-number id. 113 | - Some chunks were shortened with a '...'. 114 | - Expand relevant chunks before refactors. 115 | 116 | Important: 117 | 118 | When issuing SHOW commands, DON'T issue any other command. 119 | Instead, wait for the next message, for it to take effect. 120 | `.trim(); 121 | 122 | return `${basePrompt}\n\n${contextInstructions}`.trim(); 123 | } 124 | 125 | /** 126 | * Parses a block ID from a '?' command input. 127 | * - Empty input after '?' returns null (show full context). 128 | * - 12-digit input returns as-is (full ID). 129 | * - Numeric input is multiplied by 1,000,000 and padded to 12 digits (partial ID). 130 | * - Invalid input returns undefined (error). 131 | * @param input The user's input string (e.g., '?', '?123', '?123456789012'). 132 | * @returns Parsed block ID, null, or undefined. 133 | */ 134 | function parseBlockId(input: string): string | null | undefined { 135 | const trimmed = input.replace('?', '').trim(); 136 | if (trimmed === '') { 137 | return null; // Show full context 138 | } 139 | if (/^\d{12}$/.test(trimmed)) { 140 | return trimmed; // Full ID 141 | } 142 | const num = parseFloat(trimmed); 143 | if (!isNaN(num)) { 144 | const idNum = Math.floor(num * 1000000); 145 | return idNum.toString().padStart(12, '0'); 146 | } 147 | return undefined; // Invalid input 148 | } 149 | 150 | /** 151 | * Extracts the content of a specific block from the full context. 152 | * @param fullContext The complete context string. 153 | * @param blockId The 12-digit block ID to extract. 154 | * @returns The block content or an error message if not found. 155 | */ 156 | function extractBlockContent(fullContext: string, blockId: string): string { 157 | const blockPattern = new RegExp(`^${blockId}:\\s*\\n[\\s\\S]*?(?=^\\d{12}:|\\z)`, 'm'); 158 | const match = fullContext.match(blockPattern); 159 | return match ? match[0].trim() : `Block ID ${blockId} not found.`; 160 | } 161 | 162 | /** 163 | * Main application logic, handling user input and AI interactions. 164 | */ 165 | async function main() { 166 | const program = new Command(); 167 | program 168 | .argument('', 'Model shortcode') 169 | .argument('[path]', 'Repository path', '.') 170 | .option('-i, --include ', 'Include patterns', '') 171 | .option('-e, --exclude ', 'Exclude patterns', '') 172 | .parse(process.argv); 173 | 174 | const [model, repoPath = '.'] = program.args; 175 | 176 | // Initialize with no files loaded 177 | let includePatterns: RegExp[] = []; 178 | const excludePatterns = program.opts().exclude 179 | ? program.opts().exclude.split(',').map((p: string) => new RegExp(p)) 180 | : undefined; 181 | 182 | const repo = await RepoManager.load(repoPath, { include: includePatterns, exclude: excludePatterns }); 183 | const ai = await GenAI(model); 184 | 185 | let shownChunks: Record = {}; 186 | let aiCommandOutputs: string[] = []; 187 | let userCommandOutputs: string[] = []; 188 | const history: string[] = []; 189 | 190 | const homeDir = process.env.HOME || process.env.USERPROFILE || ''; 191 | const logDir = path.join(homeDir, '.ai', 'chatsh3_history'); 192 | if (!fs.existsSync(logDir)) { 193 | fs.mkdirSync(logDir, { recursive: true }); 194 | } 195 | const timestamp = new Date().toISOString().replace(/:/g, '-'); 196 | const logFile = path.join(logDir, `conversation_${timestamp}.txt`); 197 | 198 | function log(message: string) { 199 | fs.appendFileSync(logFile, message + '\n', 'utf8'); 200 | } 201 | 202 | const welcomeMessage = `\x1b[1mWelcome to ChatSH!\x1b[0m\nModel: ${MODELS[model]}`; 203 | console.log(welcomeMessage); 204 | log(welcomeMessage); 205 | 206 | const rl = readline.createInterface({ 207 | input: process.stdin, 208 | output: process.stdout, 209 | prompt: '\x1b[1mλ ' // Bold prompt 210 | }); 211 | 212 | rl.prompt(); 213 | 214 | rl.on('line', async (line) => { 215 | process.stdout.write("\x1b[0m"); 216 | line = line.trim(); 217 | if (line.startsWith('.')) { 218 | const ext = line.slice(1).trim(); 219 | if (ext) { 220 | const includePattern = new RegExp(`.*\\.${escapeRegex(ext)}$`); 221 | includePatterns = [includePattern]; 222 | shownChunks = {}; // Reset shown chunks when changing context 223 | await repo.refresh({ include: includePatterns, exclude: excludePatterns }); 224 | console.log(`Work context updated to include *.${ext} files.`); 225 | log(`Work context updated to include *.${ext} files.`); 226 | } else { 227 | console.log('Invalid extension. Please specify an extension, e.g., ".hs".'); 228 | log('Invalid extension. Please specify an extension, e.g., ".hs".'); 229 | } 230 | } else if (line.startsWith('?')) { 231 | const blockId = parseBlockId(line); 232 | if (blockId === undefined) { 233 | console.log('Invalid block ID. Please enter a valid number or exactly 12 digits.'); 234 | log(`λ ${line}\nInvalid block ID. Please enter a valid number or exactly 12 digits.`); 235 | } else { 236 | const fullContext = repo.view( 237 | Object.fromEntries( 238 | Object.entries(shownChunks).filter(([_, value]) => value === true) 239 | ) as Record 240 | ); 241 | let displayContext: string; 242 | if (blockId === null) { 243 | displayContext = fullContext; 244 | } else { 245 | displayContext = extractBlockContent(fullContext, blockId); 246 | } 247 | console.log(displayContext); 248 | 249 | const systemPromptTokenCount = tokenCount(getSystemPrompt(repo, shownChunks)); 250 | const totalChatTokenCount = history.reduce((sum, msg) => sum + tokenCount(msg), 0); 251 | const totalMessages = history.length; 252 | 253 | console.log('\x1b[33m%s\x1b[0m', `msg_number: ${totalMessages}`); 254 | console.log('\x1b[33m%s\x1b[0m', `msg_tokens: ${totalChatTokenCount}`); 255 | console.log('\x1b[33m%s\x1b[0m', `sys_tokens: ${systemPromptTokenCount}`); 256 | console.log('\x1b[33m%s\x1b[0m', `tot_tokens: ${systemPromptTokenCount + totalChatTokenCount}`); 257 | 258 | log(`λ ${line}`); 259 | log(displayContext); 260 | log(`\x1b[33mmsg_number: ${totalMessages}\x1b[0m`); 261 | log(`\x1b[33mmsg_tokens: ${totalChatTokenCount}\x1b[0m`); 262 | log(`\x1b[33msys_tokens: ${systemPromptTokenCount}\x1b[0m`); 263 | log(`\x1b[33mtot_tokens: ${systemPromptTokenCount + totalChatTokenCount}\x1b[0m`); 264 | } 265 | } else if (line.startsWith('!')) { 266 | const cmd = line.slice(1).trim(); 267 | const output = await executeCommand(cmd); 268 | console.log(output); // Print output to console 269 | log(`λ !${cmd}`); 270 | log(output); 271 | userCommandOutputs.push(`!${cmd}\n\\sh\n${output}\n\\\``); 272 | } else { 273 | const fullMessage = [ 274 | ...aiCommandOutputs.map(output => `\\sh\n${output}\n\\\``), 275 | ...userCommandOutputs, 276 | line 277 | ].join('\n'); 278 | log(`λ ${fullMessage}`); 279 | history.push(fullMessage); 280 | 281 | const response = await ai.ask(fullMessage, { system: getSystemPrompt(repo, shownChunks), stream: true }) as string; 282 | 283 | log(response); 284 | history.push(response); 285 | 286 | // Parse AI response for commands using response 287 | const showMatches = [...response.matchAll(//g)]; 288 | for (const match of showMatches) { 289 | const id = match[1]; 290 | shownChunks[id] = true; 291 | } 292 | 293 | const hideMatches = [...response.matchAll(//g)]; 294 | for (const match of hideMatches) { 295 | const id = match[1]; 296 | delete shownChunks[id]; 297 | } 298 | 299 | const editMatches = [...response.matchAll(/(.*?)<\/EDIT>|/gs)]; 300 | const edits: Record = {}; 301 | for (const match of editMatches) { 302 | if (match[1] && match[2] !== undefined) { 303 | edits[match[1]] = match[2]; 304 | } else if (match[3]) { 305 | edits[match[3]] = ''; 306 | } 307 | } 308 | if (Object.keys(edits).length > 0) { 309 | await repo.edit(edits); 310 | } 311 | 312 | const runMatches = [...response.matchAll(/(.*?)<\/RUN>/gs)]; 313 | aiCommandOutputs = []; 314 | for (const match of runMatches) { 315 | const script = match[1].trim(); 316 | const permission = await new Promise((resolve) => { 317 | rl.question('\x1b[31mExecute this command? [Y/N] \x1b[0m', (answer) => { 318 | resolve(answer.trim().toUpperCase()); 319 | }); 320 | }); 321 | if (permission === 'Y' || permission === '') { 322 | const output = await executeCommand(script); 323 | console.log('\x1b[2m%s\x1b[0m', output.trim()); // Print output in dim color 324 | aiCommandOutputs.push(output); 325 | log(`Executed command:\n${script}\nOutput:\n${output}`); 326 | } else { 327 | console.log('\x1b[33mCommand skipped.\x1b[0m'); 328 | aiCommandOutputs.push("(skipped)"); 329 | log(`Skipped command:\n${script}`); 330 | } 331 | } 332 | userCommandOutputs = []; 333 | } 334 | repo.refresh({ include: includePatterns, exclude: excludePatterns }); 335 | rl.prompt(); 336 | }); 337 | } 338 | 339 | main(); 340 | -------------------------------------------------------------------------------- /ChatSH_prompt.txt: -------------------------------------------------------------------------------- 1 | GenAI.ts 2 | ======= 3 | GenAI.ts is a TypeScript library providing a unified interface for interacting with various AI language models from providers like OpenAI, Anthropic, Google, and others. It enables stateful chat interactions, allowing users to send messages and receive responses from AI models seamlessly. 4 | 5 | The library abstracts the complexities of different AI APIs, enabling easy switching between models or providers without code changes. It supports features like streaming responses, temperature control, and system prompts where applicable. 6 | 7 | Usage 8 | ----- 9 | ```typescript 10 | import { GenAI } from './GenAI'; 11 | 12 | async function main() { 13 | const ai = await GenAI("g"); // Model: GPT-4o 14 | 15 | // Options 16 | const opts = { 17 | system: "You are a helpful assistant.", 18 | temperature: 0.0, 19 | stream: true, 20 | }; 21 | 22 | // Send a message 23 | const response1 = await ai.ask("Hello, how are you?", opts); 24 | console.log(response1); 25 | 26 | // Send another message 27 | const response2 = await ai.ask("What did I just say?", opts); 28 | console.log(response2); 29 | 30 | // Get conversation history 31 | const history = await ai.ask(null, opts); 32 | console.log(history); 33 | } 34 | ``` 35 | In this example, we create a chat instance for GPT-4o, send two messages, and then retrieve the conversation history. 36 | 37 | Models 38 | ------ 39 | The library supports various AI models via shortcodes defined in the `MODELS` export: 40 | 41 | - `g`: GPT-4o 42 | - `G`: o3-mini 43 | - `o`: o1 44 | - `cm`: Claude-3.5-Haiku 45 | - `c`: Claude-3.5-Sonnet 46 | - `C`: Claude-3.5-Sonnet (latest) 47 | - `d`: DeepSeek-Chat 48 | - `D`: DeepSeek-Reasoner 49 | - `lm`: Llama-3.1-8B-Instruct 50 | - `l`: Llama-3.3-70B-Instruct 51 | - `L`: Llama-3.1-405B-Instruct 52 | - `i`: Gemini-2.0-Pro 53 | - `I`: Gemini-2.0-Flash 54 | - `x`: Grok-3 55 | - `X`: Grok-3-Think 56 | 57 | Use uppercase letters (e.g., `G`) for smarter, slower versions where available. You can also use full model names if not listed. 58 | 59 | API Reference 60 | ------------- 61 | ### GenAI 62 | Creates and returns a chat instance for the specified model. 63 | 64 | **Signature:** `async function GenAI(modelShortcode: string): Promise` 65 | **Parameters:** 66 | - `modelShortcode: string` - Model shortcode (e.g., "g") or full model name. 67 | **Returns:** A promise resolving to a `ChatInstance`. 68 | 69 | ### ChatInstance 70 | Interface for chat interactions. 71 | 72 | #### ask 73 | **Signature:** `ask(userMessage: string | null, options: AskOptions): Promise` 74 | **Parameters:** 75 | - `userMessage: string | null` - Message to send. If `null`, returns conversation history. 76 | - `options: AskOptions` - Configuration options. 77 | **Returns:** 78 | - If `userMessage` is a string: AI's response as a string. 79 | - If `userMessage` is `null`: Object containing conversation history. 80 | **Note:** When `stream` is `true`, the response is streamed to `stdout`, and the full response is still returned as a string. 81 | 82 | ### AskOptions 83 | Options for the `ask` method: 84 | 85 | - `system?: string` - System prompt to set assistant behavior. 86 | - `temperature?: number` - Controls response randomness (0.0 to 1.0). Default: 0.0. 87 | - `max_tokens?: number` - Maximum tokens to generate. Default: 8192. 88 | - `stream?: boolean` - Enable streaming. Default: `true` where supported. 89 | - `system_cacheable?: boolean` - Allow caching the system message (Anthropic-specific). 90 | - `reasoning_effort?: string` - Set reasoning effort (DeepSeek-specific). 91 | 92 | **Note:** Not all options apply to every model; unsupported options are ignored. 93 | 94 | ### MODELS 95 | Record mapping shortcodes to model names. See [Models](#models) for details. 96 | 97 | ### tokenCount 98 | Estimates token count using GPT-4o's tokenizer. 99 | 100 | **Signature:** `function tokenCount(text: string): number` 101 | **Parameters:** 102 | - `text: string` - Text to analyze. 103 | **Returns:** Estimated token count. 104 | **Note:** This is an approximation; actual counts may vary by model. 105 | 106 | Setup 107 | ----- 108 | Ensure API keys are set in `~/.config/.token` (e.g., `~/.config/openai.token`). Supported vendors: `openai`, `anthropic`, `deepseek`, `openrouter`, `gemini`, `grok`. 109 | 110 | For OpenRouter, the library sets the `HTTP-Referer` header to `"https://github.com/OpenRouterTeam/openrouter-examples"`. 111 | 112 | Additional Notes 113 | ---------------- 114 | - **Streaming:** When enabled, responses are streamed to `stdout`. For DeepSeek models, reasoning content is displayed in dim text. 115 | - **Model-Specific Features:** Some models have unique behaviors (e.g., o1/o3 series handle streaming and temperature differently). 116 | - **Token Estimation:** `tokenCount` uses GPT-4o's tokenizer, which may differ from other models' tokenization. 117 | 118 | . 119 | . 120 | . 121 | . 122 | . 123 | . 124 | . 125 | . 126 | . 127 | . 128 | . 129 | . 130 | . 131 | . 132 | . 133 | . 134 | . 135 | . 136 | . 137 | . 138 | . 139 | . 140 | . 141 | . 142 | . 143 | 144 | # RepoManager 145 | 146 | RepoManager is a TypeScript library designed to manage codebases by breaking 147 | files into chunks—blocks of non-empty lines separated by blank lines. Each chunk 148 | gets a unique, stable 12-digit ID, making it easy to view or edit specific parts 149 | of your code and sync changes to disk automatically. 150 | 151 | ## What It Does 152 | 153 | - Splits files into chunks with stable IDs. 154 | - Lets you view or edit chunks selectively. 155 | - Automatically saves changes to the filesystem. 156 | - Filters files with regex patterns. 157 | 158 | Here's how to use it: 159 | 160 | ### Step 1: Load a Repository 161 | 162 | Use `RepoManager.load()` to load a directory into memory. 163 | 164 | ```typescript 165 | import { RepoManager } from 'repomanager'; 166 | 167 | // Load './my-repo', skipping 'node_modules' 168 | const repo = await RepoManager.load('./my-repo', { 169 | exclude: [/node_modules/] 170 | }); 171 | ``` 172 | 173 | Options: 174 | - `exclude`: Regex to skip files (e.g., node_modules). 175 | - `include`: Regex to include specific files (defaults to all). 176 | - Ignores files listed in `.cshignore` if it exists. 177 | 178 | ### Step 2: View the Repository 179 | 180 | Use `view()` to see your codebase, expanding specific chunks by ID. 181 | 182 | ```typescript 183 | console.log(repo.view({ '000000000000': true })); 184 | ``` 185 | 186 | Output format: 187 | ``` 188 | [file/path.js] 189 | 000000000000: 190 | function hello() { 191 | console.log("Hello, world!"); 192 | } 193 | 000001000000: 194 | console.log("Shortened chunk")... 195 | ``` 196 | 197 | Chunks not listed in `shownChunks` are shortened (e.g., first line + ...). 198 | 199 | ### Step 3: Edit Chunks 200 | 201 | Use `edit()` to modify chunks by ID. Changes sync to disk automatically. 202 | 203 | Replace a Chunk: 204 | ```typescript 205 | await repo.edit({ 206 | '000001000000': ` 207 | function add(a, b) { 208 | return a + b; 209 | }' 210 | }); 211 | ``` 212 | 213 | . 214 | . 215 | . 216 | . 217 | . 218 | . 219 | . 220 | . 221 | . 222 | . 223 | . 224 | . 225 | . 226 | . 227 | . 228 | . 229 | . 230 | . 231 | . 232 | . 233 | . 234 | . 235 | . 236 | 237 | read the docs above to learn how the RepoManager and GenAI modules work. then, 238 | implement ChatSH, a terminal-based, vendor-agnostic AI Chat app. ChatSH will be 239 | similar to ChatGPT, except that it runs on the terminal, and has shell access, 240 | i.e., it can run bash scripts. moreover, the system prompt for ChatSH will also 241 | include a *shortened snapshot* of a repository, using the RepoManager module. 242 | its system prompt is: 243 | 244 | ```txt 245 | This conversation is running inside a terminal session. 246 | 247 | To better assist me, I'll let you run bash commands on my computer. 248 | 249 | To do so, include, anywhere in your answer, a bash script, as follows: 250 | 251 | 252 | ls -la 253 | 254 | 255 | I'll soon give you a shortened context of the files I'm working on. 256 | 257 | You can issue the following context management commands: 258 | 259 | - \`\`: Expands a chunk. 260 | - \`\`: Shortens a chunk. 261 | - \`\`: Removes a chunk. 262 | - \`new_content\`: Replaces a chunk's contents. 263 | 264 | Include these commands anywhere in your answer, and I'll execute them. 265 | 266 | The work context is: 267 | 268 | ${workContext} 269 | 270 | Notes: 271 | - Chunks are labelled with a 12-number id. 272 | - Some chunks were shortened with a '...'. 273 | ``` 274 | 275 | note that workContext is obtained from repo.view(), using RepoManager. the show 276 | and hide commands edit a state of ChatSH, which maps chunk ids to true or false, 277 | depending on whether they're expanded or collapsed. we pass that to RepoManager 278 | when constructing the system prompt. finally, the edit command will just call 279 | repo.edit(), which will modify the prompt. 280 | 281 | note that, when the workContext is empty (for example, when the user calls 282 | ChatSH with an empty 'include'), there is no need to include the context 283 | management related parts of the system prompt, so, omit them in that case. 284 | 285 | when a RUN command is executed, the script will get the output from console, and 286 | prepend it to the next user message. this will allow the AI to see the result. 287 | for example, consider the interaction below: 288 | 289 | user: Please, list all files in this dir, using the "-la" flag 290 | 291 | chatsh: Sure, I'll do it. 292 | 293 | ls -la 294 | 295 | 296 | user: 297 | ```sh 298 | drwxr-xr-x@ 5 v staff 160B Feb 23 14:59 ./ 299 | drwxr-xr-x@ 16 v staff 512B Feb 23 15:18 ../ 300 | drwxr-xr-x@ 12 v staff 384B Feb 23 14:58 .git/ 301 | -rw-r--r--@ 1 v staff 302B Feb 23 14:59 bar.js 302 | -rw-r--r--@ 1 v staff 233B Feb 23 14:59 foo.js 303 | ``` 304 | 305 | now, delete the bar.js file 306 | 307 | --- 308 | 309 | in the interaction above, the user never actually wrote that sh block; they just 310 | said "now, delete the bar.js file". but the ChatSH script automatically inserted 311 | that output, allowing the AI to see the same thing as the user did. reason about 312 | this carefully, to make sure this is handled elegantly and in a sensible way. 313 | for example, stdout/stderr must be treated carefully. 314 | 315 | the ChatSH command must be called like: 316 | 317 | $ csh M 318 | 319 | this will start csh, with the model 'M'. then, the console will be cleared, and 320 | the user will see something like: 321 | 322 | ``` 323 | Welcome to ChatSH! 324 | Model: full_model_name 325 | 326 | λ 327 | ``` 328 | 329 | the user can then start typing something, and it will appear. when the user 330 | presses , it will be sent to the AI. when the user presses backtick, it 331 | will be handled correctly. reason about this to make this smooth and well done. 332 | 333 | the user can use -i and -e to include/exclude a list of regexes. a common use 334 | case is to use -i with an empty regex, which means the context on the system 335 | prompt will be empty. 336 | 337 | if the user types just '?', we will show them the current context (i.e., the 338 | shortened repository), and some stats, including total token count on the 339 | context, and total token count in the entire conversation. you can use the 340 | 'tokenCount(str) -> number' function exported by the GenAI module for that. 341 | 342 | if the user types '!something', it will execute a sh command directly, without 343 | calling or involving the AI. these command-output pairs will be accumulated and 344 | prepended to the next user AI message. example: 345 | 346 | Welcome to ChatSH! 347 | - model: ... 348 | 349 | λ !ls 350 | foo.js 351 | 352 | λ !cat foo.js 353 | console.log("Hello, world!") 354 | 355 | λ please overwrite foo.js, making it pt-br instead 356 | 357 | if the user enters these 3 exact likes, it will only call the AI after the 3rd 358 | line, with the following message: 359 | 360 | !ls 361 | ```sh 362 | foo.js 363 | ``` 364 | 365 | !cat foo.js 366 | ```sh 367 | console.log("Hello, world!") 368 | ``` 369 | 370 | please overwrite foo.js, making it pt-br instead 371 | 372 | --- 373 | 374 | note that the results of the commands issued by the IA in the message *before* 375 | that will be included *before* the user's chain of commands, in a sh block as 376 | explained before. 377 | 378 | use stablished npm libraries to make your file short when possible. do not 379 | reinvent the wheel. 380 | 381 | save the full chat history (including user commands, ai responses, system 382 | outputs, etc.) to ~/.ai/chatsh3_history/ directory, with a file name like: 383 | conversation_2025-02-20T22-44-38-472Z.txt 384 | these logs should be appended dynamically to the file as the session goes 385 | 386 | remember: when the system runs a command, both the user and the AI must be able 387 | to see its output. when printing it to the user, color it *dim*. 388 | 389 | also, make the like where the user enters the command *bold*. 390 | 391 | finally, before executing commands provided by the AI, you must ask the user 392 | for permission, with a RED colored message like: 393 | 394 | Execute 1 command? [Y/N] 395 | 396 | if the user presses enter without an input, we default to running the command. 397 | 398 | write below the complete ChatSH.ts file. 399 | -------------------------------------------------------------------------------- /GenAI.md: -------------------------------------------------------------------------------- 1 | GenAI.ts 2 | ======= 3 | GenAI.ts is a TypeScript library providing a unified interface for interacting with various AI language models from providers like OpenAI, Anthropic, Google, and others. It enables stateful chat interactions, allowing users to send messages and receive responses from AI models seamlessly. 4 | 5 | The library abstracts the complexities of different AI APIs, enabling easy switching between models or providers without code changes. It supports features like streaming responses, temperature control, and system prompts where applicable. 6 | 7 | Usage 8 | ----- 9 | ```typescript 10 | import { GenAI } from './GenAI'; 11 | 12 | async function main() { 13 | const ai = await GenAI("g"); // Model: GPT-4o 14 | 15 | // Options 16 | const opts = { 17 | system: "You are a helpful assistant.", 18 | temperature: 0.0, 19 | stream: true, 20 | }; 21 | 22 | // Send a message 23 | const response1 = await ai.ask("Hello, how are you?", opts); 24 | console.log(response1); 25 | 26 | // Send another message 27 | const response2 = await ai.ask("What did I just say?", opts); 28 | console.log(response2); 29 | 30 | // Get conversation history 31 | const history = await ai.ask(null, opts); 32 | console.log(history); 33 | } 34 | ``` 35 | In this example, we create a chat instance for GPT-4o, send two messages, and then retrieve the conversation history. 36 | 37 | Models 38 | ------ 39 | The library supports various AI models via shortcodes defined in the `MODELS` export: 40 | 41 | - `g`: GPT-4o 42 | - `G`: o3-mini 43 | - `o`: o1 44 | - `cm`: Claude-3.5-Haiku 45 | - `c`: Claude-3.5-Sonnet 46 | - `C`: Claude-3.5-Sonnet (latest) 47 | - `d`: DeepSeek-Chat 48 | - `D`: DeepSeek-Reasoner 49 | - `lm`: Llama-3.1-8B-Instruct 50 | - `l`: Llama-3.3-70B-Instruct 51 | - `L`: Llama-3.1-405B-Instruct 52 | - `i`: Gemini-2.0-Pro 53 | - `I`: Gemini-2.0-Flash 54 | - `x`: Grok-3 55 | - `X`: Grok-3-Think 56 | 57 | Use uppercase letters (e.g., `G`) for smarter, slower versions where available. You can also use full model names if not listed. 58 | 59 | API Reference 60 | ------------- 61 | ### GenAI 62 | Creates and returns a chat instance for the specified model. 63 | 64 | **Signature:** `async function GenAI(modelShortcode: string): Promise` 65 | **Parameters:** 66 | - `modelShortcode: string` - Model shortcode (e.g., "g") or full model name. 67 | **Returns:** A promise resolving to a `ChatInstance`. 68 | 69 | ### ChatInstance 70 | Interface for chat interactions. 71 | 72 | #### ask 73 | **Signature:** `ask(userMessage: string | null, options: AskOptions): Promise` 74 | **Parameters:** 75 | - `userMessage: string | null` - Message to send. If `null`, returns conversation history. 76 | - `options: AskOptions` - Configuration options. 77 | **Returns:** 78 | - If `userMessage` is a string: AI's response as a string. 79 | - If `userMessage` is `null`: Object containing conversation history. 80 | **Note:** When `stream` is `true`, the response is streamed to `stdout`, and the full response is still returned as a string. 81 | 82 | ### AskOptions 83 | Options for the `ask` method: 84 | 85 | - `system?: string` - System prompt to set assistant behavior. 86 | - `temperature?: number` - Controls response randomness (0.0 to 1.0). Default: 0.0. 87 | - `max_tokens?: number` - Maximum tokens to generate. Default: 8192. 88 | - `stream?: boolean` - Enable streaming. Default: `true` where supported. 89 | - `system_cacheable?: boolean` - Allow caching the system message (Anthropic-specific). 90 | - `reasoning_effort?: string` - Set reasoning effort (DeepSeek-specific). 91 | 92 | **Note:** Not all options apply to every model; unsupported options are ignored. 93 | 94 | ### MODELS 95 | Record mapping shortcodes to model names. See [Models](#models) for details. 96 | 97 | ### tokenCount 98 | Estimates token count using GPT-4o's tokenizer. 99 | 100 | **Signature:** `function tokenCount(text: string): number` 101 | **Parameters:** 102 | - `text: string` - Text to analyze. 103 | **Returns:** Estimated token count. 104 | **Note:** This is an approximation; actual counts may vary by model. 105 | 106 | Setup 107 | ----- 108 | Ensure API keys are set in `~/.config/.token` (e.g., `~/.config/openai.token`). Supported vendors: `openai`, `anthropic`, `deepseek`, `openrouter`, `gemini`, `grok`. 109 | 110 | For OpenRouter, the library sets the `HTTP-Referer` header to `"https://github.com/OpenRouterTeam/openrouter-examples"`. 111 | 112 | Additional Notes 113 | ---------------- 114 | - **Streaming:** When enabled, responses are streamed to `stdout`. For DeepSeek models, reasoning content is displayed in dim text. 115 | - **Model-Specific Features:** Some models have unique behaviors (e.g., o1/o3 series handle streaming and temperature differently). 116 | - **Token Estimation:** `tokenCount` uses GPT-4o's tokenizer, which may differ from other models' tokenization. 117 | -------------------------------------------------------------------------------- /GenAI.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs/promises'; 2 | import * as os from 'os'; 3 | import * as path from 'path'; 4 | import { AnthropicChat } from './Vendors/Anthropic'; 5 | import { GeminiChat } from './Vendors/Gemini'; 6 | import { GrokChat } from './Vendors/Grok'; 7 | import { OpenAIChat } from './Vendors/OpenAI'; 8 | import { countTokens } from 'gpt-tokenizer/model/gpt-4o'; 9 | 10 | export const MODELS: Record = { 11 | g: 'gpt-4.1', 12 | G: 'gpt-4.5-preview-2025-02-27', 13 | o: 'o4-mini', 14 | O: 'o3', 15 | cm: 'claude-3-5-haiku-20241022', 16 | c: 'claude-sonnet-4-20250514', 17 | C: 'claude-opus-4-20250514', 18 | ct: 'claude-sonnet-4-20250514-think', 19 | Ct: 'claude-opus-4-20250514-think', 20 | d: 'deepseek-chat', 21 | D: 'deepseek-reasoner', 22 | lm: 'meta-llama/llama-3.1-8b-instruct', 23 | l: 'meta-llama/llama-3.3-70b-instruct', 24 | L: 'meta-llama/llama-3.1-405b-instruct', 25 | i: 'gemini-2.5-pro-preview-05-06', 26 | I: 'gemini-2.0-flash-thinking-exp-01-21', 27 | x: "grok-3", 28 | X: "grok-3-think", 29 | }; 30 | 31 | export interface AskOptions { 32 | system?: string; 33 | temperature?: number; 34 | max_tokens?: number; 35 | max_completion_tokens?: number; 36 | stream?: boolean; 37 | system_cacheable?: boolean; 38 | reasoning_effort?: string; 39 | } 40 | 41 | export interface ChatInstance { 42 | ask(userMessage: string | null, options: AskOptions): Promise; 43 | } 44 | 45 | function getVendor(model: string): string { 46 | if (model.startsWith('gpt') || model.startsWith('o1') || model.startsWith('o3') || model.startsWith('o4') || model.startsWith('chat')) { 47 | return 'openai'; 48 | } else if (model.startsWith('claude')) { 49 | return 'anthropic'; 50 | } else if (model.startsWith('deepseek')) { 51 | return 'deepseek'; 52 | } else if (model.startsWith('meta')) { 53 | return 'openrouter'; 54 | } else if (model.startsWith('gemini')) { 55 | return 'gemini'; 56 | } else if (model.startsWith('grok')) { 57 | return 'grok'; 58 | } else { 59 | throw new Error(`Unsupported model: ${model}`); 60 | } 61 | } 62 | 63 | async function getToken(vendor: string): Promise { 64 | const tokenPath = path.join(os.homedir(), '.config', `${vendor}.token`); 65 | try { 66 | return (await fs.readFile(tokenPath, 'utf8')).trim(); 67 | } catch (err) { 68 | console.error(`Error reading ${vendor}.token file:`, (err as Error).message); 69 | process.exit(1); 70 | } 71 | } 72 | 73 | export async function GenAI(modelShortcode: string): Promise { 74 | const model = MODELS[modelShortcode] || modelShortcode; 75 | const vendor = getVendor(model); 76 | 77 | if (['openai', 'deepseek', 'openrouter'].includes(vendor)) { 78 | const apiKey = await getToken(vendor); 79 | let baseURL: string; 80 | if (vendor === 'openai') { 81 | baseURL = 'https://api.openai.com/v1'; 82 | } else if (vendor === 'deepseek') { 83 | baseURL = 'https://api.deepseek.com/v1'; 84 | } else { 85 | baseURL = 'https://openrouter.ai/api/v1'; 86 | } 87 | return new OpenAIChat(apiKey, baseURL, model, vendor); 88 | } else if (vendor === 'anthropic') { 89 | const apiKey = await getToken(vendor); 90 | return new AnthropicChat(apiKey, model); 91 | } else if (vendor === 'gemini') { 92 | const apiKey = await getToken(vendor); 93 | return new GeminiChat(apiKey, model); 94 | } else if (vendor === 'grok') { 95 | return new GrokChat(model); 96 | } else { 97 | throw new Error(`Unsupported vendor: ${vendor}`); 98 | } 99 | } 100 | 101 | export function tokenCount(text: string): number { 102 | return countTokens(text); 103 | } 104 | -------------------------------------------------------------------------------- /GenAI_Demo.ts: -------------------------------------------------------------------------------- 1 | import { GenAI } from './GenAI'; 2 | 3 | async function main() { 4 | // Available models: 5 | // - g: GPT-4o 6 | // - c: Claude 7 | // - d: DeepSeek 8 | // - l: Llama 9 | // - i: Gemini 10 | // - x: Grok 11 | const ai = await GenAI("g"); 12 | 13 | // Options 14 | const opts = { 15 | system: "You are a helpful assistant.", 16 | temperature: 0.0, 17 | stream: true, 18 | }; 19 | 20 | // Send a message 21 | console.log(await ai.ask("Hello, how are you?", opts)); 22 | 23 | // Send another message 24 | console.log(await ai.ask("What is my name?", opts)); 25 | } 26 | 27 | main(); 28 | -------------------------------------------------------------------------------- /HoleFill.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bun 2 | 3 | import * as fs from 'fs/promises'; 4 | import * as os from 'os'; 5 | import * as path from 'path'; 6 | import * as process from 'process'; 7 | import { GenAI, MODELS, tokenCount } from './GenAI'; 8 | 9 | interface AskOptions { 10 | system?: string; 11 | temperature?: number; 12 | max_tokens?: number; 13 | stream?: boolean; 14 | system_cacheable?: boolean; 15 | reasoning_effort?: string; 16 | } 17 | 18 | const SYSTEM = `You're a code completion assistant.`; 19 | const FILL = '{:FILL_HERE:}'; 20 | const TASK = 21 | `### TASK: complete the ${FILL} part of the file above. ` + 22 | `Write ONLY the needed text to replace ${FILL} by the correct completion, including correct spacing and indentation. ` + 23 | `Include the answer inside a tag.`; 24 | 25 | /* ------------------------------------------------------------------ 26 | * Utility: force every ".?." placeholder to column-0 27 | * ------------------------------------------------------------------ */ 28 | function leftAlignHoles(code: string): string { 29 | /* strip any leading spaces or tabs that precede ".?." */ 30 | return code.replace(/^([ \t]+)(\.\?\.)/gm, '$2'); 31 | } 32 | 33 | async function main(): Promise { 34 | const file = process.argv[2]; 35 | const mini = process.argv[3]; 36 | const model = process.argv[4] || 'c'; 37 | 38 | if (!file) { 39 | console.log('Usage: holefill [] []'); 40 | console.log('\nThis will complete a HOLE, written as ".?.", in , using the AI.'); 41 | process.exit(1); 42 | } 43 | 44 | const ai = await GenAI(model); 45 | 46 | /* read user files */ 47 | let file_code = await fs.readFile(file, 'utf-8'); 48 | let mini_code = mini ? await fs.readFile(mini, 'utf-8') : file_code; 49 | 50 | /* expand inline import markers in mini_code */ 51 | const expanded: string[] = []; 52 | for (const line of mini_code.split('\n')) { 53 | const m1 = line.match(/^\/\/\.\/(.*?)\/\/$/); 54 | const m2 = line.match(/^{-\.\/(.*?)-\}$/); 55 | const m = m1 || m2; 56 | if (m) { 57 | const p = path.resolve(path.dirname(file), m[1]); 58 | try { expanded.push(await fs.readFile(p, 'utf-8')); } 59 | catch { console.log('import_file:', line, 'ERROR'); process.exit(1); } 60 | } else { 61 | expanded.push(line); 62 | } 63 | } 64 | mini_code = expanded.join('\n'); 65 | 66 | /* -------------------------------------------------------------- 67 | * New behaviour: NO hole may start after column-0. 68 | * We left-align every ".?." in BOTH file_code and mini_code. 69 | * -------------------------------------------------------------- */ 70 | file_code = leftAlignHoles(file_code); 71 | mini_code = leftAlignHoles(mini_code); 72 | 73 | if (mini) await fs.writeFile(mini, mini_code, 'utf-8'); 74 | 75 | /* build prompt */ 76 | const tokens = tokenCount(mini_code); 77 | const source = mini_code.replace('.?.', FILL); 78 | const prompt = `${source}\n\n${TASK}`; 79 | 80 | await fs.mkdir(path.join(os.homedir(), '.ai'), { recursive: true }); 81 | await fs.writeFile(path.join(os.homedir(), '.ai', '.holefill'), 82 | `${SYSTEM}\n###\n${prompt}`, 'utf-8'); 83 | 84 | console.log('token_count:', tokens); 85 | console.log('model_label:', MODELS[model] || model); 86 | 87 | if (!mini_code.includes('.?.')) { console.log('No hole found.'); process.exit(1); } 88 | 89 | const replyRaw = await ai.ask(prompt, { system: SYSTEM } as AskOptions); 90 | const replyStr = typeof replyRaw === 'string' 91 | ? replyRaw 92 | : replyRaw.messages.map((m: any) => m.content).join('\n'); 93 | 94 | const wrapped = replyStr.includes('') ? replyStr : `${replyStr}`; 95 | const match = /([\s\S]*?)<\/COMPLETION>/g.exec(wrapped); 96 | if (!match) { console.error('Error: no in AI response.'); process.exit(1); } 97 | 98 | const fill = match[1].replace(/\$/g, '$$$$').replace(/^\n+|\n+$/g, ''); 99 | file_code = file_code.replace('.?.', fill); 100 | 101 | await fs.writeFile(file, file_code, 'utf-8'); 102 | 103 | const ts = new Date().toISOString().replace(/[:.]/g, '-'); 104 | const logDir = path.join(os.homedir(), '.ai', 'prompt_history'); 105 | await fs.mkdir(logDir, { recursive: true }); 106 | await fs.writeFile(path.join(logDir, `${ts}_${MODELS[model] || model}.log`), 107 | `SYSTEM:\n${SYSTEM}\n\nPROMPT:\n${prompt}\n\nREPLY:\n${wrapped}\n\n`, 'utf-8'); 108 | } 109 | 110 | main().catch(console.error); 111 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Taelin AI Scripts 2 | ================= 3 | 4 | Some AI scripts I use daily. 5 | 6 | - `chatsh`: like ChatGPT but in the terminal ([example chat](https://x.com/VictorTaelin/status/1655304645953089538)) ([example coding](https://x.com/VictorTaelin/status/1809290888356729002)) ([example refactor](https://x.com/VictorTaelin/status/1828893898594300220)) 7 | 8 | - `holefill`: I use it on VIM to fill code snippets 9 | 10 | - ~~`aiemu`: emulate any game on the terminal ([example](https://x.com/VictorTaelin/status/1790183986096116189))~~ 11 | 12 | - ~~`koder`: perform refactor requests ([example](https://x.com/VictorTaelin/status/1824489509146227192)) ([example](https://x.com/VictorTaelin/status/1811254153655558188))~~ 13 | 14 | - ~~`agda2ts`: compile Agda to/from TypeScript ([example](https://x.com/VictorTaelin/status/1837256721850306746))~~ 15 | 16 | - ~~`aoe`: refactor a huge codebase by auto-filtering chunks that need edit ([example](https://x.com/VictorTaelin/status/1873948475299111244))~~ 17 | 18 | *Note: I'm currently unifying all scripts into `chatsh`. For the old scripts, see the 'old-main' branch.* 19 | 20 | For VIM integration, this is my messy [vimrc](https://github.com/VictorTaelin/OSX/blob/master/vimrc). 21 | 22 | This repo in general is kinda gambiarra. Note: currently updating to ts! 23 | 24 | ## Usage 25 | 26 | Just `npm install -g` and run the given command the terminal. 27 | 28 | You'll need to add Anthropic/OpenAI/etc. keys to `~/.config`. 29 | 30 | ## Note 31 | 32 | Most of this scripts will save a log to `~/.ai`. If you don't want this 33 | behavior, edit the scripts to suit your needs. (TODO: add a proper option.) 34 | 35 | ## LICENSE 36 | 37 | Everything here is MIT-licensed. 38 | -------------------------------------------------------------------------------- /RepoManager.md: -------------------------------------------------------------------------------- 1 | //./RepoManager.ts// 2 | 3 | # RepoManager 4 | 5 | RepoManager is a TypeScript library designed to manage codebases by breaking 6 | files into chunks—blocks of non-empty lines separated by blank lines. Each chunk 7 | gets a unique, stable 12-digit ID, making it easy to view or edit specific parts 8 | of your code and sync changes to disk automatically. 9 | 10 | ## What It Does 11 | 12 | - Splits files into chunks with stable IDs. 13 | - Lets you view or edit chunks selectively. 14 | - Automatically saves changes to the filesystem. 15 | - Filters files with regex patterns. 16 | 17 | Here's how to use it: 18 | 19 | ### Step 1: Load a Repository 20 | 21 | Use `RepoManager.load()` to load a directory into memory. 22 | 23 | ```typescript 24 | import { RepoManager } from 'repomanager'; 25 | 26 | // Load './my-repo', skipping 'node_modules' 27 | const repo = await RepoManager.load('./my-repo', { 28 | exclude: [/node_modules/] 29 | }); 30 | ``` 31 | 32 | Options: 33 | 34 | - `exclude`: Regex to skip files (e.g., node_modules). 35 | - `include`: Regex to include specific files (defaults to all). 36 | - Ignores files listed in .cshignore if it exists. 37 | 38 | ### Step 2: View the Repository 39 | 40 | Use `view()` to see your codebase, expanding specific chunks by ID. 41 | 42 | ```typescript 43 | console.log(repo.view({ '000000000000': true })); 44 | ``` 45 | 46 | Output format: 47 | 48 | ```text 49 | [file/path.js] 50 | 000000000000: 51 | function hello() { 52 | console.log("Hello, world!"); 53 | } 54 | 000001000000: 55 | console.log("Shortened chunk")... 56 | ``` 57 | 58 | Chunks not listed in `shownChunks` are shortened (e.g., first line + ...). 59 | 60 | ### Step 3: Edit Chunks 61 | 62 | Use `edit()` to modify chunks by ID. Changes sync to disk automatically. 63 | 64 | Replace a Chunk: 65 | 66 | ```typescript 67 | await repo.edit({ 68 | '000001000000': ` 69 | function add(a, b) { 70 | return a + b; 71 | }` 72 | }); 73 | ``` 74 | 75 | TODO: add below documentation for .refresh 76 | 77 | ### Step 4: Refresh the Repository 78 | 79 | Use `refresh()` to scan for new tracked files not yet in memory. New files are split into chunks and added to the repository. 80 | 81 | ```typescript 82 | await repo.refresh({ 83 | exclude: [/node_modules/], 84 | include: [/\.ts$/] // Only refresh TypeScript files 85 | }); 86 | ``` 87 | 88 | Options: 89 | 90 | - `exclude`: Regex to skip files during refresh. 91 | - `include`: Regex to specify which files to refresh (defaults to all). 92 | - Respects .cshignore for additional filtering. 93 | -------------------------------------------------------------------------------- /RepoManager.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs/promises'; 2 | import path from 'path'; 3 | import ignore from 'ignore'; 4 | 5 | // Define common file extensions for programming languages and text files (no hidden files here) 6 | const commonExtensions = [ 7 | 'js', 'ts', 'jsx', 'tsx', // JavaScript/TypeScript 8 | 'py', // Python 9 | 'hs', 'cabal', 'project', // Haskell 10 | 'kind', // Kind 11 | 'bend', // Bend 12 | 'hvm', 'hvml', 'hvms', // HVM 13 | 'java', // Java 14 | 'c', 'cpp', 'h', 'hpp', // C/C++ 15 | 'cs', // C# 16 | 'rb', // Ruby 17 | 'go', // Go 18 | 'rs', // Rust 19 | 'php', // PHP 20 | 'swift', // Swift 21 | 'kt', // Kotlin 22 | 'scala', // Scala 23 | 'html', 'htm', 'css', // HTML/CSS 24 | 'sh', 'bash', // Shell scripts 25 | 'sql', // SQL 26 | 'md', // Markdown 27 | 'yaml', 'yml', // YAML 28 | 'json', // JSON 29 | 'xml', // XML 30 | 'properties', // Properties files 31 | 'ini', // INI files 32 | 'toml', // TOML files 33 | 'txt', // Plain text 34 | 'conf', 'cfg', 'env', // Configuration files 35 | ]; 36 | 37 | // Define specific file names that are important in repositories (including some hidden ones explicitly) 38 | const specificFiles = [ 39 | 'LICENSE', 40 | 'README', 41 | 'CHANGELOG', 42 | 'TODO', 43 | 'Dockerfile', 44 | 'Makefile', 45 | '.gitignore', 46 | '.dockerignore', 47 | '.env', 48 | '.editorconfig', 49 | ]; 50 | 51 | // Define huge directories to exclude by default 52 | const hugeDirectories = [ 53 | 'node_modules', 'dist', 'build', 'vendor', 'coverage', // JavaScript/Node.js, PHP 54 | 'dist-newstyle', // Haskell 55 | '__pycache__', '.venv', 'venv', 'env', '.eggs', 'egg-info', // Python 56 | 'target', 'out', '.gradle', '.m2', // Java 57 | 'bin', 'pkg', '.bundle', // Go, Ruby 58 | 'obj', '.cache', 'deps', 'lib', 'public', // C/C++, Clojure, Scala, static sites 59 | 'artifacts', 'tmp', 'temp', // General build/temp 60 | ]; 61 | 62 | // Escape dots in specific file names for regex (e.g., '.gitignore' -> '\\.gitignore') 63 | const escapedSpecificFiles = specificFiles.map(f => f.replace(/\./g, '\\.')); 64 | 65 | // Improved default include regexes: 66 | // 1. Include files with common extensions in any directory (hidden filtering will be handled by defaultExclude) 67 | const defaultInclude = [ 68 | new RegExp(`^.*\\.(${commonExtensions.join('|')})$`), 69 | // 2. Include specific files like 'README' or '.gitignore', hidden or not 70 | new RegExp(`(.*\\/)?(${escapedSpecificFiles.join('|')})$`), 71 | ]; 72 | 73 | // Default exclude regexes for hidden files and huge directories 74 | const defaultExclude = [ 75 | // Exclude all hidden files and directories (e.g., '.git', '.hidden.txt') 76 | new RegExp(`(^|\\/)\\.[^/]+(/.*|$)`), 77 | // Exclude large directories like 'node_modules' and their contents 78 | new RegExp(`(^|\\/)(${hugeDirectories.join('|')})\\/.*`), 79 | ]; 80 | 81 | /** Converts a 12-character ID string to a number for calculations. */ 82 | function idToNumber(id: string): number { 83 | return parseInt(id, 10); 84 | } 85 | 86 | /** Converts a number to a 12-character padded ID string. */ 87 | function numberToId(num: number): string { 88 | return num.toString().padStart(12, '0'); 89 | } 90 | 91 | /** Recursively lists all files in a directory, filtering based on ignore patterns and regexes. */ 92 | async function listFiles( 93 | dir: string, 94 | ig: ignore.Ignore, 95 | rootPath: string, 96 | include: RegExp[] | undefined, 97 | exclude: RegExp[] 98 | ): Promise { 99 | const entries = await fs.readdir(dir, { withFileTypes: true }); 100 | const files: string[] = []; 101 | for (const entry of entries) { 102 | const fullPath = path.join(dir, entry.name); 103 | const relativePath = path.relative(rootPath, fullPath); 104 | if (ig.ignores(relativePath)) continue; 105 | if (entry.isDirectory()) { 106 | const subFiles = await listFiles(fullPath, ig, rootPath, include, exclude); 107 | files.push(...subFiles); 108 | } else if (entry.isFile()) { 109 | if (include !== undefined) { 110 | if (include.length === 0) continue; 111 | if (!include.some(regex => regex.test(relativePath))) continue; 112 | } 113 | if (exclude.some(regex => regex.test(relativePath))) continue; 114 | files.push(fullPath); 115 | } 116 | } 117 | return files; 118 | } 119 | 120 | /** Shortens a chunk for summary display. */ 121 | export function shortenChunk(chunk: string): string { 122 | const lines = chunk.split('\n'); 123 | if (lines[0] === '--show--' || lines[0] === '//show//') { 124 | return lines.slice(1).join('\n'); 125 | } 126 | const isComment = (line: string) => { 127 | const trimmed = line.trim(); 128 | return trimmed.startsWith('//') || trimmed.startsWith('--') || trimmed.startsWith('#'); 129 | }; 130 | const firstLine = lines[0]; 131 | if (isComment(firstLine)) { 132 | const firstNonComment = lines.find(line => !isComment(line)); 133 | return firstNonComment ? `${firstLine}\n${firstNonComment}...` : `${firstLine}...`; 134 | } 135 | return `${firstLine}...`; 136 | } 137 | 138 | /** Manages a repository's chunks in memory with stable, padded IDs. */ 139 | export class RepoManager { 140 | private rootPath: string; 141 | private chunks: Map; 142 | private nextId: number; 143 | 144 | private constructor(rootPath: string) { 145 | this.rootPath = rootPath; 146 | this.chunks = new Map(); 147 | this.nextId = 0; 148 | } 149 | 150 | static async load( 151 | rootPath: string, 152 | options: { exclude?: RegExp[]; include?: RegExp[] } = {} 153 | ): Promise { 154 | const repo = new RepoManager(rootPath); 155 | await repo._load(options); 156 | return repo; 157 | } 158 | 159 | private async _load(options: { exclude?: RegExp[]; include?: RegExp[] }) { 160 | const ig = ignore(); 161 | const cshignorePath = path.join(this.rootPath, '.cshignore'); 162 | try { 163 | const cshignoreContent = await fs.readFile(cshignorePath, 'utf8'); 164 | ig.add(cshignoreContent); 165 | } catch (err) { 166 | // Ignore missing .cshignore 167 | } 168 | 169 | // Use user-provided include if supplied; otherwise, use defaultInclude 170 | const include = options.include !== undefined ? options.include : defaultInclude; 171 | // Use user-provided exclude if supplied; otherwise, use defaultExclude 172 | const exclude = options.exclude !== undefined ? options.exclude : defaultExclude; 173 | const files = await listFiles(this.rootPath, ig, this.rootPath, include, exclude); 174 | files.sort(); 175 | 176 | for (const file of files) { 177 | const content = await fs.readFile(file, 'utf8'); 178 | const rawChunks = content.split(/\n\s*\n/); 179 | const trimmedChunks = rawChunks 180 | .map(chunk => chunk.replace(/^\n+|\n+$/g, '')) 181 | .filter(chunk => chunk.length > 0); 182 | 183 | for (const chunkContent of trimmedChunks) { 184 | const id = numberToId(this.nextId); 185 | this.chunks.set(id, { path: file, content: chunkContent }); 186 | this.nextId += 1000000; 187 | } 188 | } 189 | } 190 | 191 | view(shownChunks: { [id: string]: true }): string { 192 | const fileChunks: { [path: string]: { id: string; content: string }[] } = {}; 193 | for (const [id, chunk] of this.chunks) { 194 | fileChunks[chunk.path] = fileChunks[chunk.path] || []; 195 | fileChunks[chunk.path].push({ id, content: chunk.content }); 196 | } 197 | 198 | // Find the smallest ID for each file 199 | const fileMinIds: { path: string; minId: number }[] = []; 200 | for (const path in fileChunks) { 201 | const ids = fileChunks[path].map(chunk => idToNumber(chunk.id)); 202 | const minId = Math.min(...ids); 203 | fileMinIds.push({ path, minId }); 204 | } 205 | 206 | // Sort files by their smallest chunk ID 207 | fileMinIds.sort((a, b) => a.minId - b.minId); 208 | 209 | let result = ''; 210 | for (const file of fileMinIds) { 211 | const filePath = file.path; 212 | result += `[${filePath}]\n`; 213 | const chunksInFile = fileChunks[filePath].sort((a, b) => idToNumber(a.id) - idToNumber(b.id)); 214 | for (const chunk of chunksInFile) { 215 | const displayContent = shownChunks[chunk.id] ? chunk.content : shortenChunk(chunk.content); 216 | result += `${chunk.id}:\n${displayContent}\n`; 217 | } 218 | } 219 | return result.trim(); 220 | } 221 | 222 | async edit(edits: { [id: string]: string }) { 223 | for (const id in edits) { 224 | if (!this.chunks.has(id)) { 225 | console.warn(`Chunk ${id} does not exist.`); 226 | continue; 227 | } 228 | const newContent = edits[id].replace(/^\n+|\n+$/g, ''); // Trim leading/trailing newlines 229 | if (newContent === '') { 230 | this.chunks.delete(id); 231 | } else { 232 | const newBlocks = newContent 233 | .split(/\n\s*\n/) 234 | .map(block => block.replace(/^\n+|\n+$/g, '')) // Trim each block 235 | .filter(block => block.length > 0); 236 | const originalChunk = this.chunks.get(id)!; 237 | const path = originalChunk.path; 238 | 239 | if (newBlocks.length === 1) { 240 | this.chunks.set(id, { path, content: newBlocks[0] }); 241 | } else if (newBlocks.length > 1) { 242 | const allIds = Array.from(this.chunks.keys()).sort((a, b) => idToNumber(a) - idToNumber(b)); 243 | const index = allIds.indexOf(id); 244 | const nextIdStr = index < allIds.length - 1 ? allIds[index + 1] : null; 245 | const base = idToNumber(id); 246 | const nextId = nextIdStr ? idToNumber(nextIdStr) : base + 1000000; 247 | const space = nextId - base; 248 | const n = newBlocks.length; 249 | const step = Math.floor(space / n); 250 | 251 | if (step < 1) { 252 | throw new Error(`Not enough space to split chunk ${id} into ${n} blocks.`); 253 | } 254 | 255 | const newIds: string[] = []; 256 | for (let i = 0; i < n; i++) { 257 | const newIdNum = base + i * step; 258 | const newIdStr = numberToId(newIdNum); 259 | if (this.chunks.has(newIdStr) && newIdStr !== id) { 260 | throw new Error(`ID collision at ${newIdStr} while splitting chunk ${id}.`); 261 | } 262 | newIds.push(newIdStr); 263 | } 264 | 265 | this.chunks.delete(id); 266 | for (let i = 0; i < n; i++) { 267 | this.chunks.set(newIds[i], { path, content: newBlocks[i] }); 268 | } 269 | } 270 | } 271 | } 272 | await this.save(); 273 | } 274 | 275 | async addFile(relativePath: string, content: string): Promise { 276 | const fullPath = path.join(this.rootPath, relativePath); 277 | try { 278 | await fs.access(fullPath); 279 | throw new Error(`File ${relativePath} already exists.`); 280 | } catch (err: unknown) { 281 | const error = err as NodeJS.ErrnoException; // Type assertion to handle Node.js errors 282 | if (error.code !== 'ENOENT') { 283 | throw err; 284 | } 285 | } 286 | const dirname = path.dirname(fullPath); 287 | await fs.mkdir(dirname, { recursive: true }); 288 | const rawChunks = content.split(/\n\s*\n/); 289 | const trimmedChunks = rawChunks 290 | .map(chunk => chunk.replace(/^\n+|\n+$/g, '')) 291 | .filter(chunk => chunk.length > 0); 292 | for (const chunkContent of trimmedChunks) { 293 | const id = numberToId(this.nextId); 294 | this.chunks.set(id, { path: fullPath, content: chunkContent }); 295 | this.nextId += 1000000; 296 | } 297 | await this.save(); 298 | } 299 | 300 | async save() { 301 | const fileChunks: { [path: string]: { id: string; content: string }[] } = {}; 302 | for (const [id, chunk] of this.chunks) { 303 | fileChunks[chunk.path] = fileChunks[chunk.path] || []; 304 | fileChunks[chunk.path].push({ id, content: chunk.content }); 305 | } 306 | 307 | for (const filePath in fileChunks) { 308 | const chunksInFile = fileChunks[filePath].sort((a, b) => idToNumber(a.id) - idToNumber(b.id)); 309 | const content = chunksInFile.map(chunk => chunk.content).join('\n\n') + '\n'; 310 | await fs.writeFile(filePath, content); 311 | } 312 | } 313 | 314 | async refresh(options: { exclude?: RegExp[]; include?: RegExp[] } = {}) { 315 | const ig = ignore(); 316 | const cshignorePath = path.join(this.rootPath, '.cshignore'); 317 | try { 318 | const cshignoreContent = await fs.readFile(cshignorePath, 'utf8'); 319 | ig.add(cshignoreContent); 320 | } catch (err) { 321 | // Ignore missing .cshignore 322 | } 323 | const include = options.include !== undefined ? options.include : defaultInclude; 324 | const exclude = options.exclude !== undefined ? options.exclude : defaultExclude; 325 | const files = await listFiles(this.rootPath, ig, this.rootPath, include, exclude); 326 | files.sort(); 327 | 328 | // Gather already tracked file paths from the current chunks 329 | const trackedPaths = new Set(); 330 | for (const chunk of this.chunks.values()) { 331 | trackedPaths.add(chunk.path); 332 | } 333 | 334 | // Add any new files that are not in the tracked paths 335 | for (const file of files) { 336 | if (!trackedPaths.has(file)) { 337 | const content = await fs.readFile(file, 'utf8'); 338 | const rawChunks = content.split(/\n\s*\n/); 339 | const trimmedChunks = rawChunks 340 | .map(chunk => chunk.replace(/^\n+|\n+$/g, '')) 341 | .filter(chunk => chunk.length > 0); 342 | for (const chunkContent of trimmedChunks) { 343 | const id = numberToId(this.nextId); 344 | this.chunks.set(id, { path: file, content: chunkContent }); 345 | this.nextId += 1000000; 346 | } 347 | } 348 | } 349 | await this.save(); 350 | } 351 | } 352 | -------------------------------------------------------------------------------- /RepoManager_Demo.ts: -------------------------------------------------------------------------------- 1 | import { RepoManager } from './RepoManager'; 2 | 3 | async function main() { 4 | // Load repository 5 | const repo = await RepoManager.load('./tmp', { exclude: [/node_modules/, /^\.[^/]/] }); 6 | 7 | // View with chunks expanded 8 | console.log(repo.view({"000001000000": true})); 9 | 10 | // Edit a block 11 | await repo.edit({"000001000000": ` 12 | function multiply(a, b) { 13 | 14 | // testing edit functionality 15 | 16 | return a * b; 17 | 18 | }` 19 | }); 20 | 21 | //// Verify 22 | //console.log(repo.view({ '000001000000': true })); 23 | } 24 | 25 | main().catch(console.error); 26 | -------------------------------------------------------------------------------- /Vendors/Anthropic.ts: -------------------------------------------------------------------------------- 1 | import Anthropic from "@anthropic-ai/sdk"; 2 | import { AskOptions, ChatInstance } from "../GenAI"; 3 | 4 | // --------------------------------------------------------------------------- 5 | // NOTE: The Anthropic SDK’s type exports have been unstable across recent 6 | // versions. To keep compilation green regardless of future renames, we 7 | // avoid direct named‑type imports and fall back to `any` where necessary. 8 | // --------------------------------------------------------------------------- 9 | 10 | type Role = "user" | "assistant"; 11 | 12 | export class AnthropicChat implements ChatInstance { 13 | private readonly client: Anthropic; 14 | private readonly model: string; 15 | private readonly messages: { role: Role; content: any }[] = []; 16 | 17 | constructor(apiKey: string, model: string) { 18 | this.client = new Anthropic({ 19 | apiKey, 20 | defaultHeaders: { 21 | "anthropic-beta": "prompt-caching-2024-07-31", 22 | }, 23 | }); 24 | this.model = model; 25 | } 26 | 27 | async ask( 28 | userMessage: string | null, 29 | options: AskOptions = {}, 30 | ): Promise { 31 | if (userMessage === null) return { messages: this.messages }; 32 | 33 | // ── options ---------------------------------------------------------- 34 | const enableThinking = this.model.endsWith("-think"); 35 | const baseModel = enableThinking ? this.model.replace("-think", "") : this.model; 36 | 37 | let { 38 | system, 39 | temperature = enableThinking ? 1 : 0, 40 | max_tokens = 32_000, 41 | stream = true, 42 | system_cacheable = false, 43 | } = options; 44 | 45 | // ── build message history ------------------------------------------- 46 | this.messages.push({ role: "user", content: userMessage }); 47 | 48 | // -------------------------------------------------------------------- 49 | // Build request params (typeless to dodge SDK type churn) 50 | // -------------------------------------------------------------------- 51 | const params: any = { 52 | model: baseModel, 53 | temperature, 54 | max_tokens, 55 | stream, 56 | messages: this.messages, 57 | }; 58 | 59 | if (system) { 60 | params.system = system_cacheable 61 | ? [{ type: "text", text: system, cache_control: { type: "ephemeral" } }] 62 | : system; 63 | } 64 | 65 | if (enableThinking) { 66 | params.thinking = { 67 | type: "enabled", 68 | budget_tokens: 4096, 69 | }; 70 | } 71 | 72 | // ── perform request -------------------------------------------------- 73 | let plain = ""; 74 | 75 | if (stream) { 76 | const streamResp: AsyncIterable = (await this.client.messages.create( 77 | params, 78 | )) as any; 79 | 80 | let printedReasoning = false; 81 | for await (const event of streamResp) { 82 | if (event.type === "content_block_delta") { 83 | const delta: any = event.delta; 84 | if (delta.type === "thinking_delta") { 85 | process.stdout.write(`\x1b[2m${delta.thinking}\x1b[0m`); 86 | plain += delta.thinking; 87 | printedReasoning = true; 88 | } else if (delta.type === "text_delta") { 89 | if (printedReasoning) { 90 | process.stdout.write("\n"); 91 | printedReasoning = false; 92 | } 93 | process.stdout.write(delta.text); 94 | plain += delta.text; 95 | } 96 | } 97 | } 98 | process.stdout.write("\n"); 99 | this.messages.push({ role: "assistant", content: plain }); 100 | } else { 101 | const message: any = await this.client.messages.create({ ...params, stream: false }); 102 | const blocks: any[] = message.content; 103 | let printedReasoning = false; 104 | for (const block of blocks) { 105 | if (block.type === "thinking") { 106 | process.stdout.write(`\x1b[2m${block.thinking}\x1b[0m`); 107 | plain += block.thinking; 108 | printedReasoning = true; 109 | } else if (block.type === "text") { 110 | if (printedReasoning) { 111 | process.stdout.write("\n"); 112 | printedReasoning = false; 113 | } 114 | process.stdout.write(block.text); 115 | plain += block.text; 116 | } 117 | } 118 | process.stdout.write("\n"); 119 | this.messages.push({ role: "assistant", content: blocks }); 120 | } 121 | 122 | return plain; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /Vendors/Gemini.ts: -------------------------------------------------------------------------------- 1 | import { 2 | GoogleGenerativeAI, 3 | HarmCategory, 4 | HarmBlockThreshold, 5 | type GenerationConfig, 6 | type SafetySetting, 7 | } from "@google/generative-ai"; 8 | import type { AskOptions, ChatInstance } from "../GenAI"; 9 | 10 | /** Internal representation of a chat turn */ 11 | type Role = "user" | "assistant"; 12 | interface Turn { 13 | role: Role; 14 | content: string; 15 | } 16 | 17 | /** 18 | * Gemini implementation of the HoleFill ChatInstance. 19 | * Fixes two long-standing issues: 20 | * 21 | * 1. **Malformed completions** – we now pass the system prompt via 22 | * `systemInstruction`, drop the in-prompt “System: …\nUser: …” hack and 23 | * always wait for the final aggregated response, so the returned text 24 | * contains the full `` block. 25 | * 2. **Hidden thinking trace** – streaming output is parsed for 26 | * `thinking_delta` chunks (the same event names Anthropic uses). These 27 | * deltas are echoed to stdout in grey, exactly like the Sonnet handler. 28 | */ 29 | export class GeminiChat implements ChatInstance { 30 | private readonly client: GoogleGenerativeAI; 31 | private readonly modelName: string; 32 | 33 | private chat: any = null; // lazy-initialised ChatSession 34 | private history: Turn[] = []; // local running history 35 | 36 | constructor(apiKey: string, modelName: string) { 37 | this.client = new GoogleGenerativeAI(apiKey); 38 | this.modelName = modelName; 39 | } 40 | 41 | /* --------------------------------------------------------------------- */ 42 | 43 | async ask( 44 | userMessage: string | null, 45 | opts: AskOptions = {}, 46 | ): Promise { 47 | if (userMessage === null) { 48 | return { messages: this.history }; 49 | } 50 | 51 | const { 52 | system, 53 | temperature = 0, 54 | max_tokens = 100_000, 55 | stream = true, 56 | } = opts; 57 | 58 | /* ---------- create the chat session (once) ------------------------- */ 59 | if (!this.chat) { 60 | const generationConfig: GenerationConfig = { 61 | temperature, 62 | maxOutputTokens: max_tokens, 63 | }; 64 | 65 | const safetySettings: SafetySetting[] = [ 66 | { category: HarmCategory.HARM_CATEGORY_HARASSMENT, threshold: HarmBlockThreshold.BLOCK_NONE }, 67 | { category: HarmCategory.HARM_CATEGORY_HATE_SPEECH, threshold: HarmBlockThreshold.BLOCK_NONE }, 68 | { category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, threshold: HarmBlockThreshold.BLOCK_NONE }, 69 | { category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT, threshold: HarmBlockThreshold.BLOCK_NONE }, 70 | ]; 71 | 72 | const model = this.client.getGenerativeModel({ 73 | model: this.modelName, 74 | systemInstruction: system 75 | ? { role: "model", parts: [{ text: system }] } 76 | : undefined, 77 | generationConfig, 78 | safetySettings, 79 | }); 80 | 81 | /* convert local history → SDK format */ 82 | const sdkHistory = this.history.map(turn => ({ 83 | role : turn.role === "assistant" ? "model" : "user", 84 | parts : [{ text: turn.content }], 85 | })); 86 | 87 | this.chat = model.startChat({ history: sdkHistory }); 88 | } 89 | 90 | /* ---------- send user prompt -------------------------------------- */ 91 | this.history.push({ role: "user", content: userMessage }); 92 | 93 | let answer = ""; 94 | let printedGrey = false; // to add a newline between reasoning & answer 95 | 96 | if (stream) { 97 | const resp = await this.chat.sendMessageStream(userMessage); 98 | 99 | for await (const chunk of resp.stream) { 100 | /* Anthropic-style reasoning tokens come through as thinking_delta */ 101 | if (chunk.type === "content_block_delta") { 102 | if (chunk.delta?.type === "thinking_delta") { 103 | process.stdout.write(`\x1b[2m${chunk.delta.thinking}\x1b[0m`); 104 | printedGrey = true; 105 | answer += chunk.delta.thinking; // keep for completeness 106 | continue; 107 | } 108 | if (chunk.delta?.type === "text_delta") { 109 | if (printedGrey) { 110 | process.stdout.write("\n"); // line break after thoughts 111 | printedGrey = false; 112 | } 113 | process.stdout.write(chunk.delta.text); 114 | answer += chunk.delta.text; 115 | continue; 116 | } 117 | } 118 | 119 | /* Fallback for non-typed chunks (old SDKs simply expose .text()) */ 120 | const txt = typeof (chunk as any).text === "function" 121 | ? (chunk as any).text() 122 | : (chunk as any).text ?? ""; 123 | if (txt) { 124 | process.stdout.write(txt); 125 | answer += txt; 126 | } 127 | } 128 | process.stdout.write("\n"); 129 | 130 | /* guarantee we didn’t miss tail content */ 131 | try { 132 | const full = (await resp.response).text(); 133 | if (full && !answer.endsWith(full)) answer += full; 134 | } catch { /* ignore */ } 135 | } else { 136 | /* non-stream fallback */ 137 | const resp = await this.chat.sendMessage(userMessage); 138 | answer = (await resp.response).text(); 139 | } 140 | 141 | this.history.push({ role: "assistant", content: answer }); 142 | return answer; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /Vendors/Grok.ts: -------------------------------------------------------------------------------- 1 | import { Scraper } from 'agent-twitter-client-taelin-fork'; 2 | import { AskOptions, ChatInstance } from "../GenAI"; 3 | import * as fs from 'fs/promises'; 4 | import * as os from 'os'; 5 | import * as path from 'path'; 6 | 7 | export class GrokChat implements ChatInstance { 8 | private scraper: Scraper | null = null; 9 | private conversationId: string | null = null; 10 | private messages: { role: "user" | "assistant"; content: string }[] = []; 11 | private cookies: any[] | null = null; 12 | private model: string; 13 | private systemPrompt: string | null = null; 14 | 15 | constructor(model: string) { 16 | this.model = model; 17 | } 18 | 19 | private async initialize(): Promise { 20 | if (!this.scraper) { 21 | const configPath = path.join(os.homedir(), '.config', 'twitter.pwd'); 22 | let credentials; 23 | try { 24 | const data = await fs.readFile(configPath, 'utf8'); 25 | credentials = JSON.parse(data); 26 | } catch (err) { 27 | console.error('Error reading twitter.pwd file:', (err as Error).message); 28 | throw new Error('Failed to load Twitter credentials'); 29 | } 30 | 31 | const { user, pass, email } = credentials; 32 | if (!user || !pass) { 33 | throw new Error('twitter.pwd must contain "user" and "pass" fields'); 34 | } 35 | 36 | this.scraper = new Scraper(); 37 | 38 | const cookiesPath = path.join(os.homedir(), '.config', 'twitter.cookies'); 39 | try { 40 | const cookiesData = await fs.readFile(cookiesPath, 'utf8'); 41 | const cookieStrings = JSON.parse(cookiesData); 42 | const loadedCookies = cookieStrings.filter((cookie: any) => cookie !== undefined); 43 | await this.scraper.setCookies(loadedCookies); 44 | } catch (err) { 45 | this.cookies = null; 46 | } 47 | 48 | if (!(await this.scraper.isLoggedIn())) { 49 | try { 50 | await this.scraper.login(user, pass, email || undefined); 51 | this.cookies = await this.scraper.getCookies(); 52 | const cookieStrings = this.cookies.map(cookie => cookie.toString()); 53 | await fs.writeFile(cookiesPath, JSON.stringify(cookieStrings), 'utf8'); 54 | } catch (err) { 55 | throw new Error('Twitter login failed'); 56 | } 57 | } 58 | } 59 | } 60 | 61 | async ask(userMessage: string | null, options: AskOptions): Promise { 62 | if (userMessage === null) { 63 | return { messages: this.messages }; 64 | } 65 | 66 | await this.initialize(); 67 | 68 | let { system, stream = true } = options; 69 | 70 | // Prepend system prompt to user message if provided 71 | if (system) { 72 | userMessage = `${system}\n---\n${userMessage}`; 73 | } 74 | 75 | const messagesToSend: { role: "user" | "assistant"; content: string }[] = [{ role: 'user', content: userMessage }]; 76 | 77 | try { 78 | const modelName = this.model.replace("-think", ""); 79 | const isReasoning = this.model.endsWith("-think"); 80 | const response = await this.scraper!.grokChat({ 81 | messages: messagesToSend, 82 | conversationId: this.conversationId ?? undefined, 83 | isReasoning, 84 | returnSearchResults: false, 85 | returnCitations: false, 86 | stream, 87 | ...options, 88 | }); 89 | process.stdout.write("\n"); 90 | 91 | this.conversationId = response.conversationId; 92 | this.messages = response.messages; 93 | 94 | if (response.rateLimit?.isRateLimited) { 95 | console.warn(`Rate limit exceeded: ${response.rateLimit.message}`); 96 | } 97 | 98 | return response.message; 99 | } catch (err) { 100 | console.error('Error interacting with Grok:', (err as Error).message); 101 | throw err; 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /Vendors/OpenAI.ts: -------------------------------------------------------------------------------- 1 | import OpenAI from "openai"; 2 | import { AskOptions, ChatInstance } from "../GenAI"; 3 | 4 | /** 5 | * OpenAI wrapper supporting GPT‑series and o‑series reasoning models. 6 | */ 7 | 8 | type Role = "user" | "assistant" | "system" | "developer"; 9 | 10 | const isOSeries = (m: string) => /^o[0-9]/.test(m); 11 | const controlRole = (m: string): Role => (isOSeries(m) ? "developer" : "system"); 12 | 13 | export class OpenAIChat implements ChatInstance { 14 | private readonly client: OpenAI; 15 | private readonly model: string; 16 | private readonly vendor: string; 17 | private readonly messages: { role: Role; content?: string }[] = []; 18 | 19 | constructor(apiKey: string, baseURL: string, model: string, vendor: string) { 20 | const defaultHeaders = 21 | vendor === "openrouter" 22 | ? { "HTTP-Referer": "https://github.com/OpenRouterTeam/openrouter-examples" } 23 | : undefined; 24 | this.client = new OpenAI({ apiKey, baseURL, defaultHeaders }); 25 | this.model = model; 26 | this.vendor = vendor; 27 | } 28 | 29 | private ensureControlMessage(content?: string) { 30 | if (!content) return; 31 | const role = controlRole(this.model); 32 | if (this.messages[0] && (this.messages[0].role === "system" || this.messages[0].role === "developer")) { 33 | this.messages[0] = { role, content }; 34 | } else { 35 | this.messages.unshift({ role, content }); 36 | } 37 | } 38 | 39 | async ask(userMessage: string | null, options: AskOptions = {}): Promise { 40 | if (userMessage === null) return { messages: this.messages }; 41 | 42 | const useOSeries = isOSeries(this.model); 43 | 44 | const { 45 | system, 46 | temperature = useOSeries ? 1 : 0, 47 | stream: wantStream = true, 48 | max_tokens = 8_192, 49 | max_completion_tokens = 65_000, 50 | reasoning_effort = "high", 51 | } = options; 52 | 53 | this.ensureControlMessage(system); 54 | this.messages.push({ role: "user", content: userMessage }); 55 | 56 | // Build base request body 57 | const body: Record = { 58 | model: this.model, 59 | messages: this.messages as any, 60 | temperature, 61 | ...(useOSeries ? { max_completion_tokens, reasoning_effort } : { max_tokens }), 62 | }; 63 | 64 | // OpenRouter flag for reasoning tokens — OpenAI rejects it 65 | if (this.vendor === "openrouter") { 66 | body.include_reasoning = true; 67 | } 68 | 69 | const doStream = !!wantStream; 70 | let visible = ""; 71 | 72 | try { 73 | if (doStream) { 74 | const streamParams = body as unknown as OpenAI.Chat.Completions.ChatCompletionCreateParamsStreaming; 75 | const stream = await this.client.chat.completions.create({ ...streamParams, stream: true }); 76 | 77 | let printingReasoning = false; 78 | for await (const chunk of stream) { 79 | const delta: any = chunk.choices[0]?.delta; 80 | const reasoningPart = delta?.reasoning_content ?? delta?.reasoning; 81 | if (reasoningPart) { 82 | process.stdout.write(`\x1b[2m${reasoningPart}\x1b[0m`); 83 | printingReasoning = true; 84 | continue; 85 | } 86 | if (delta?.content) { 87 | if (printingReasoning) { 88 | printingReasoning = false; 89 | process.stdout.write("\n"); 90 | } 91 | process.stdout.write(delta.content); 92 | visible += delta.content; 93 | } 94 | } 95 | process.stdout.write("\n"); 96 | } else { 97 | const respParams = body as unknown as OpenAI.Chat.Completions.ChatCompletionCreateParamsNonStreaming; 98 | const resp: any = await this.client.chat.completions.create(respParams); 99 | const msg: any = resp.choices[0]?.message ?? {}; 100 | const reasoningText = msg.reasoning_content ?? msg.reasoning; 101 | if (reasoningText) process.stdout.write(`\x1b[2m${reasoningText}\x1b[0m\n`); 102 | visible = msg.content ?? ""; 103 | process.stdout.write(visible + "\n"); 104 | } 105 | } catch (err: any) { 106 | console.error("[OpenAIChat] API error:", err?.message || err); 107 | throw err; 108 | } 109 | 110 | this.messages.push({ role: "assistant", content: visible }); 111 | return visible; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /issue/Parse.hs: -------------------------------------------------------------------------------- 1 | {-./dump.txt-} 2 | {-./Type.hs-} 3 | 4 | -- TASK: now, create a Parser for Bend's Term Type 5 | 6 | ```haskell 7 | module Parse where 8 | 9 | import Data.Char (isAsciiLower, isAsciiUpper, isDigit) 10 | import Data.Void 11 | import Highlight (highlightError) -- Assuming this exists and works as in Kind7 example 12 | import Text.Megaparsec 13 | import Text.Megaparsec.Char 14 | import qualified Data.List.NonEmpty as NE 15 | import qualified Text.Megaparsec.Char.Lexer as L 16 | 17 | import Type -- The new Bend Type.hs 18 | 19 | type Parser = Parsec Void String 20 | 21 | skip :: Parser () 22 | skip = L.space space1 (L.skipLineComment "//") (L.skipBlockComment "/*" "*/") 23 | 24 | lexeme :: Parser a -> Parser a 25 | lexeme = L.lexeme skip 26 | 27 | symbol :: String -> Parser String 28 | symbol = L.symbol skip 29 | 30 | parens :: Parser a -> Parser a 31 | parens = between (symbol "(") (symbol ")") 32 | 33 | angles :: Parser a -> Parser a 34 | angles = between (symbol "<") (symbol ">") 35 | 36 | braces :: Parser a -> Parser a 37 | braces = between (symbol "{") (symbol "}") 38 | 39 | brackets :: Parser a -> Parser a 40 | brackets = between (symbol "[") (symbol "]") 41 | 42 | isNameInit :: Char -> Bool 43 | isNameInit c = isAsciiLower c || isAsciiUpper c || c == '_' 44 | 45 | isNameChar :: Char -> Bool 46 | isNameChar c = isAsciiLower c || isAsciiUpper c || isDigit c || c == '_' || c == '$' -- Added $ for HVM compatibility if needed 47 | 48 | name :: Parser String 49 | name = lexeme $ do 50 | h <- satisfy isNameInit "letter or underscore" 51 | t <- many (satisfy isNameChar "letter, digit, or underscore") 52 | return (h : t) 53 | 54 | formatError :: String -> ParseErrorBundle String Void -> String 55 | formatError input bundle = 56 | let errorWithSource = NE.head $ fst $ attachSourcePos errorOffset (bundleErrors bundle) (bundlePosState bundle) 57 | err = fst errorWithSource 58 | pos = snd errorWithSource 59 | sourcePos = pstateSourcePos $ bundlePosState bundle NE.!! sourcePosPrettyLength errorWithSource 60 | lin = unPos (sourceLine sourcePos) 61 | col = unPos (sourceColumn sourcePos) 62 | msg = parseErrorTextPretty err 63 | highlighted = highlightError (lin, col) (lin, col + 1) input 64 | in "\nPARSE_ERROR\n" ++ msg ++ "\n" ++ 65 | "At line " ++ show lin ++ ", column " ++ show col ++ ":\n" ++ 66 | highlighted 67 | where 68 | sourcePosPrettyLength :: SourcePos -> Int 69 | sourcePosPrettyLength sp = fromIntegral $कारों (\(SourcePos _ _ c) -> unPos c) sp - 1 70 | 71 | 72 | parseTerm :: Parser Term 73 | parseTerm = do 74 | term <- parseTermIni 75 | parseTermEnd term 76 | 77 | parseTermIni :: Parser Term 78 | parseTermIni = choice 79 | [ symbol "*" >> return Set 80 | , symbol "⊥" >> return Emp 81 | , symbol "⊤" >> return Uni 82 | , try (symbol "()" >> return One) -- try because '(' can start other things 83 | , symbol "𝔹" >> return Bit 84 | , symbol "#0" >> return Bt0 85 | , symbol "#1" >> return Bt1 86 | , symbol "ℕ" >> return Nat 87 | , symbol "0" >> return Zer 88 | , try (symbol "[]" >> return Nil) -- try because '[' can start Vec 89 | , symbol "μ" *> parseFix 90 | , symbol "Π" *> parseAll 91 | , symbol "Σ" *> parseSig 92 | , symbol "!" *> parseLet 93 | , symbol "?" *> parseMet 94 | , symbol "↑" *> (Suc <$> parseTerm) 95 | , symbol "^" *> parseIdx 96 | , parseLambdaLike -- Handles all λ forms (λx.f, λ{}, λ{():f}, etc.) 97 | , try parseAppParen -- (f x y) 98 | , try parseTupParen -- (a,b) 99 | , parens parseTerm -- (x) for grouping 100 | , parseBraceWrapped -- Handles {l}, {=}, {:=} 101 | , parseVarOrKeyword -- Must be late, as 'name' is general 102 | ] 103 | 104 | parseTermEnd :: Term -> Parser Term 105 | parseTermEnd term = choice 106 | [ do { try (symbol "=="); b <- parseTerm; symbol ":"; t <- parseTerm; parseTermEnd (Eql term b t) } 107 | , do { symbol "<>"; t <- parseTerm; parseTermEnd (Con term t) } 108 | , do { symbol "::"; t <- parseTerm; parseTermEnd (Chk term t) } 109 | , do { symbol "+"; t <- parseTerm; parseTermEnd (Add term t) } 110 | , try $ do { lookAhead (symbol "[]" >> notFollowedBy (satisfy isNameChar)); symbol "[]"; parseTermEnd (Lst term) } 111 | , do { content <- brackets parseTerm; parseTermEnd (Vec term content) } 112 | , return term 113 | ] 114 | 115 | parseVarOrKeyword :: Parser Term 116 | parseVarOrKeyword = do 117 | k <- name 118 | case k of 119 | "Set" -> return Set 120 | "Nat" -> return Nat 121 | "Bit" -> return Bit 122 | "True" -> return Bt1 123 | "False" -> return Bt0 124 | _ -> return (Var k) 125 | 126 | parseIdx :: Parser Term 127 | parseIdx = Idx <$> lexeme L.decimal <*> angles parseTerm 128 | 129 | parseAnn :: Parser Term -- Not directly in parseTermIni, but used by other parsers if needed, or could be an operator 130 | parseAnn = angles $ Ann <$> parseTerm <*> (symbol ":" *> parseTerm) 131 | 132 | parseBits :: Parser Bits 133 | parseBits = choice 134 | [ symbol "E" >> return E 135 | , symbol "O" >> O <$> parseBits 136 | , symbol "I" >> I <$> parseBits 137 | ] 138 | 139 | parseMet :: Parser Term 140 | parseMet = do 141 | metaName <- name 142 | symbol ":" 143 | metaType <- parseTerm 144 | metaSeed <- option E (symbol "#" *> lexeme parseBits) 145 | metaCtx <- option [] (braces (parseTerm `sepBy` symbol ",")) 146 | symbol ";" 147 | fBodyTerm <- parseTerm 148 | return $ Met (Meta metaName metaType metaSeed metaCtx (\_ -> fBodyTerm)) 149 | 150 | parseLet :: Parser Term 151 | parseLet = do 152 | x <- name 153 | symbol ":" 154 | t <- parseTerm 155 | symbol "=" 156 | v <- parseTerm 157 | symbol ";" 158 | fBodyTerm <- parseTerm 159 | return $ Let x t v (\_ -> fBodyTerm) 160 | 161 | parseFix :: Parser Term 162 | parseFix = do 163 | x <- name 164 | symbol "." 165 | fBodyTerm <- parseTerm 166 | return $ Fix x (\_ -> fBodyTerm) 167 | 168 | parseLambdaLike :: Parser Term 169 | parseLambdaLike = symbol "λ" *> choice 170 | [ braces $ choice 171 | [ try (symbol "}" >> return Efq) 172 | , try (symbol "():" *> parseTerm <* symbol "}" >>= \f -> return (Use f)) 173 | , try (symbol "#0:" *> parseTerm <* symbol ";#1:" <*> parseTerm <* symbol "}" >>= \(f,t) -> return (Bif f t)) 174 | , try (symbol "(,):" *> parseTerm <* symbol "}" >>= \f -> return (Get f)) 175 | , try (symbol "[]:" *> parseTerm <* symbol ";<>:" <*> parseTerm <* symbol "}" >>= \(n,c) -> return (Mat n c)) 176 | , try (symbol "0:" *> parseTerm <* symbol ";+:" <*> parseTerm <* symbol "}" >>= \(z,s) -> return (Swi z s)) 177 | , symbol "{=}:" *> parseTerm <* symbol "}" >>= \f -> return (Rwt f) 178 | ] 179 | , do -- Normal Lam: λx.f 180 | x <- name 181 | symbol "." 182 | bodyTerm <- parseTerm 183 | return $ Lam x (\_ -> bodyTerm) 184 | ] 185 | 186 | parseSig :: Parser Term 187 | parseSig = do 188 | x <- name 189 | symbol ":" 190 | a <- parseTerm 191 | symbol "." 192 | bBodyTerm <- parseTerm 193 | return $ Sig x a (\_ -> bBodyTerm) 194 | 195 | parseAll :: Parser Term 196 | parseAll = do 197 | x <- name 198 | symbol ":" 199 | a <- parseTerm 200 | symbol "." 201 | bBodyTerm <- parseTerm 202 | return $ All x a (\_ -> bBodyTerm) 203 | 204 | parseAppParen :: Parser Term 205 | parseAppParen = parens (foldl App <$> parseTerm <*> many parseTerm) 206 | 207 | parseTupParen :: Parser Term 208 | parseTupParen = parens (Tup <$> parseTerm <* symbol "," <*> parseTerm) 209 | 210 | parseBraceWrapped :: Parser Term 211 | parseBraceWrapped = symbol "{" *> choice 212 | [ try (symbol "=" *> symbol "}" *> return Rfl) 213 | , try (symbol ":=" *> symbol "}" *> return Tst) 214 | , Fin <$> parseTerm <* symbol "}" 215 | ] 216 | 217 | -- Entry points 218 | doParseTerm :: String -> String -> Either String Term 219 | doParseTerm filename code = 220 | case parse (skip *> parseTerm <* eof) filename code of 221 | Left bundle -> Left (formatError code bundle) 222 | Right term -> Right term -- Assuming 'bind' is a separate step if needed for HOAS bodies 223 | 224 | doReadTerm :: String -> Term 225 | doReadTerm input = 226 | case doParseTerm "" input of 227 | Left err -> error err 228 | Right term -> term 229 | 230 | ``` 231 | -------------------------------------------------------------------------------- /issue/README.md: -------------------------------------------------------------------------------- 1 | # Problem 2 | 3 | Using `holefill Parse.hs .fill.tmp i` will ask Gemini to complete the `Parse.hs` 4 | file, using `dump.txt` and `Type.hs` as contexts. For some reason, though, its 5 | completion is much different than what we get if we just pass `.fill.tmp` 6 | directly to Gemini on Google AI Studio. Also, I can not figure out how to stream 7 | Gemini's thinking tokens, to mimic the behavior of the AI Studio. 8 | 9 | Also, OpenAI's o4-mini and o3 aren't showing thinking tokens either. 10 | Enabling them would be appreciated. 11 | -------------------------------------------------------------------------------- /issue/Type.hs: -------------------------------------------------------------------------------- 1 | -- New Bend 2 | 3 | module Type where 4 | 5 | data Bits = O Bits | I Bits | E 6 | type Name = String 7 | type Body = Term -> Term 8 | 9 | data Meta = Meta { 10 | metaName :: Name, 11 | metaType :: Term, 12 | metaSeed :: Bits, 13 | metaCtx :: [Term], 14 | metaBody :: Body 15 | } 16 | 17 | data Term 18 | = Var Name -- x 19 | | Idx Int Term -- ^i 20 | | Sub Term -- x 21 | | Set -- * 22 | | Ann Term Term -- 23 | | Chk Term Term -- x::t 24 | | Met Meta -- ?x:T#S{C};f 25 | | Let Name Term Term Body -- !x:t=v;f 26 | | Fix Name Body -- μx.f 27 | | Emp -- ⊥ 28 | | Efq -- λ{} 29 | | Uni -- ⊤ 30 | | One -- () 31 | | Use Term -- λ{():f} 32 | | Bit -- 𝔹 33 | | Bt0 -- #0 34 | | Bt1 -- #1 35 | | Bif Term Term -- λ{#0:f;#1:t} 36 | | Sig Name Term Body -- Σx:A.B 37 | | Tup Term Term -- (a,b) 38 | | Get Term -- λ{(,):f} 39 | | All Name Term Body -- Πx:A.B 40 | | Lam Name Body -- λx.f 41 | | App Term Term -- (f x) 42 | | Fin Term -- {l} 43 | | Nat -- ℕ 44 | | Zer -- 0 45 | | Suc Term -- ↑n 46 | | Add Term Term -- a+b 47 | | Swi Term Term -- λ{0:z;+:s} 48 | | Lst Term -- t[] 49 | | Vec Term Term -- t[l] 50 | | Nil -- [] 51 | | Con Term Term -- h<>t 52 | | Mat Term Term -- λ{[]:n;<>:c} 53 | | Eql Term Term Term -- (a==b):t 54 | | Rfl -- {=} 55 | | Tst -- {:=} 56 | | Rwt Term -- λ{{=}:f} 57 | 58 | instance Show Term where 59 | show (Var x) = x 60 | show (Idx i t) = "^" ++ show i ++ "<" ++ show t ++ ">" 61 | show (Sub t) = show t 62 | show Set = "*" 63 | show (Ann a b) = "<" ++ show a ++ ":" ++ show b ++ ">" 64 | show (Chk t ty) = show t ++ "::" ++ show ty 65 | show (Met m) = "?" ++ metaName m 66 | show (Let x t v f) = "!" ++ x ++ ":" ++ show t ++ "=" ++ show v ++ ";" ++ show (f (Var x)) 67 | show (Fix x f) = "μ" ++ x ++ "." ++ show (f (Var x)) 68 | show Emp = "⊥" 69 | show Efq = "λ{}" 70 | show Uni = "⊤" 71 | show One = "()" 72 | show (Use t) = "λ{():" ++ show t ++ "}" 73 | show Bit = "𝔹" 74 | show Bt0 = "#0" 75 | show Bt1 = "#1" 76 | show (Bif f t) = "λ{#0:" ++ show f ++ ";#1:" ++ show t ++ "}" 77 | show (Sig x a b) = "Σ" ++ x ++ ":" ++ show a ++ "." ++ show (b (Var x)) 78 | show (Tup a b) = "(" ++ show a ++ "," ++ show b ++ ")" 79 | show (Get t) = "λ{(,):" ++ show t ++ "}" 80 | show (All x a b) = "Π" ++ x ++ ":" ++ show a ++ "." ++ show (b (Var x)) 81 | show (Lam x f) = "λ" ++ x ++ "." ++ show (f (Var x)) 82 | show (App f a) = "(" ++ show f ++ " " ++ show a ++ ")" 83 | show (Fin t) = "{" ++ show t ++ "}" 84 | show Nat = "ℕ" 85 | show Zer = "0" 86 | show (Suc n) = "↑" ++ show n 87 | show (Add a b) = show a ++ "+" ++ show b 88 | show (Swi z s) = "λ{0:" ++ show z ++ ";+:" ++ show s ++ "}" 89 | show (Lst t) = show t ++ "[]" 90 | show (Vec t l) = show t ++ "[" ++ show l ++ "]" 91 | show Nil = "[]" 92 | show (Con h t) = show h ++ "<>" ++ show t 93 | show (Mat n c) = "λ{[]:" ++ show n ++ ";<>:" ++ show c ++ "}" 94 | show (Eql a b t) = "(" ++ show a ++ "==" ++ show b ++ "):" ++ show t 95 | show Rfl = "{=}" 96 | show Tst = "{:=}" 97 | show (Rwt t) = "λ{{=}:" ++ show t ++ "}" 98 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tai_scripts", 3 | "version": "0.1.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "tai_scripts", 9 | "version": "0.1.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@anthropic-ai/sdk": "^0.39.0", 13 | "@google/generative-ai": "^0.24.0", 14 | "@openrouter/ai-sdk-provider": "^0.4.5", 15 | "@portkey-ai/gateway": "^1.9.15", 16 | "agent-twitter-client-taelin-fork": "^0.0.26", 17 | "apify-client": "^2.12.2", 18 | "commander": "^13.1.0", 19 | "gateway": "^1.0.0", 20 | "googleapis": "^148.0.0", 21 | "gpt-tokenizer": "^2.9.0", 22 | "groq-sdk": "^0.19.0", 23 | "ignore": "^7.0.3", 24 | "minimist": "^1.2.8", 25 | "oauth-1.0a": "^2.2.6", 26 | "openai": "^4.95.0", 27 | "portkey-ai": "^1.8.0", 28 | "typescript": "^5.8.3" 29 | }, 30 | "bin": { 31 | "csh": "ChatSH.ts", 32 | "holefill": "HoleFill.ts" 33 | }, 34 | "devDependencies": { 35 | "@types/minimist": "^1.2.5" 36 | } 37 | }, 38 | "node_modules/@ai-sdk/provider": { 39 | "version": "1.0.9", 40 | "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-1.0.9.tgz", 41 | "integrity": "sha512-jie6ZJT2ZR0uVOVCDc9R2xCX5I/Dum/wEK28lx21PJx6ZnFAN9EzD2WsPhcDWfCgGx3OAZZ0GyM3CEobXpa9LA==", 42 | "dependencies": { 43 | "json-schema": "^0.4.0" 44 | }, 45 | "engines": { 46 | "node": ">=18" 47 | } 48 | }, 49 | "node_modules/@ai-sdk/provider-utils": { 50 | "version": "2.1.10", 51 | "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-2.1.10.tgz", 52 | "integrity": "sha512-4GZ8GHjOFxePFzkl3q42AU0DQOtTQ5w09vmaWUf/pKFXJPizlnzKSUkF0f+VkapIUfDugyMqPMT1ge8XQzVI7Q==", 53 | "dependencies": { 54 | "@ai-sdk/provider": "1.0.9", 55 | "eventsource-parser": "^3.0.0", 56 | "nanoid": "^3.3.8", 57 | "secure-json-parse": "^2.7.0" 58 | }, 59 | "engines": { 60 | "node": ">=18" 61 | }, 62 | "peerDependencies": { 63 | "zod": "^3.0.0" 64 | }, 65 | "peerDependenciesMeta": { 66 | "zod": { 67 | "optional": true 68 | } 69 | } 70 | }, 71 | "node_modules/@anthropic-ai/sdk": { 72 | "version": "0.39.0", 73 | "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.39.0.tgz", 74 | "integrity": "sha512-eMyDIPRZbt1CCLErRCi3exlAvNkBtRe+kW5vvJyef93PmNr/clstYgHhtvmkxN82nlKgzyGPCyGxrm0JQ1ZIdg==", 75 | "dependencies": { 76 | "@types/node": "^18.11.18", 77 | "@types/node-fetch": "^2.6.4", 78 | "abort-controller": "^3.0.0", 79 | "agentkeepalive": "^4.2.1", 80 | "form-data-encoder": "1.7.2", 81 | "formdata-node": "^4.3.2", 82 | "node-fetch": "^2.6.7" 83 | } 84 | }, 85 | "node_modules/@apify/consts": { 86 | "version": "2.40.0", 87 | "resolved": "https://registry.npmjs.org/@apify/consts/-/consts-2.40.0.tgz", 88 | "integrity": "sha512-2coaQ97ddsQ4+QRybqGbPE4irqfmkSaUPlbUPQvIcmT+PLdFT1t1iSU61Yy2T1UW5wN3K6UDAqFWNIqxxb0apg==" 89 | }, 90 | "node_modules/@apify/log": { 91 | "version": "2.5.13", 92 | "resolved": "https://registry.npmjs.org/@apify/log/-/log-2.5.13.tgz", 93 | "integrity": "sha512-gxvWyD9JWBkLoTX7UfQ4s0F32/UfF4T8TG4jAl2CE0vNKr0COOJFkLmmyWnTNSVDL+yGC+LZp3mtbPnB+l6Sog==", 94 | "dependencies": { 95 | "@apify/consts": "^2.37.0", 96 | "ansi-colors": "^4.1.1" 97 | } 98 | }, 99 | "node_modules/@aws-crypto/sha256-js": { 100 | "version": "5.2.0", 101 | "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", 102 | "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", 103 | "dependencies": { 104 | "@aws-crypto/util": "^5.2.0", 105 | "@aws-sdk/types": "^3.222.0", 106 | "tslib": "^2.6.2" 107 | }, 108 | "engines": { 109 | "node": ">=16.0.0" 110 | } 111 | }, 112 | "node_modules/@aws-crypto/util": { 113 | "version": "5.2.0", 114 | "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", 115 | "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", 116 | "dependencies": { 117 | "@aws-sdk/types": "^3.222.0", 118 | "@smithy/util-utf8": "^2.0.0", 119 | "tslib": "^2.6.2" 120 | } 121 | }, 122 | "node_modules/@aws-sdk/types": { 123 | "version": "3.734.0", 124 | "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.734.0.tgz", 125 | "integrity": "sha512-o11tSPTT70nAkGV1fN9wm/hAIiLPyWX6SuGf+9JyTp7S/rC2cFWhR26MvA69nplcjNaXVzB0f+QFrLXXjOqCrg==", 126 | "dependencies": { 127 | "@smithy/types": "^4.1.0", 128 | "tslib": "^2.6.2" 129 | }, 130 | "engines": { 131 | "node": ">=18.0.0" 132 | } 133 | }, 134 | "node_modules/@cfworker/json-schema": { 135 | "version": "4.1.1", 136 | "resolved": "https://registry.npmjs.org/@cfworker/json-schema/-/json-schema-4.1.1.tgz", 137 | "integrity": "sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==" 138 | }, 139 | "node_modules/@crawlee/types": { 140 | "version": "3.12.2", 141 | "resolved": "https://registry.npmjs.org/@crawlee/types/-/types-3.12.2.tgz", 142 | "integrity": "sha512-mdSN8FSOGLzPDyO3wC5k6BvZKv467rvrLsIqqAkiN87TgQI5lwV+k2bBQGdajzcjDQn+taWG67xDbbZg6BvFVw==", 143 | "dependencies": { 144 | "tslib": "^2.4.0" 145 | }, 146 | "engines": { 147 | "node": ">=16.0.0" 148 | } 149 | }, 150 | "node_modules/@google/generative-ai": { 151 | "version": "0.24.0", 152 | "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.0.tgz", 153 | "integrity": "sha512-fnEITCGEB7NdX0BhoYZ/cq/7WPZ1QS5IzJJfC3Tg/OwkvBetMiVJciyaan297OvE4B9Jg1xvo0zIazX/9sGu1Q==", 154 | "engines": { 155 | "node": ">=18.0.0" 156 | } 157 | }, 158 | "node_modules/@hono/node-server": { 159 | "version": "1.13.8", 160 | "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.13.8.tgz", 161 | "integrity": "sha512-fsn8ucecsAXUoVxrUil0m13kOEq4mkX4/4QozCqmY+HpGfKl74OYSn8JcMA8GnG0ClfdRI4/ZSeG7zhFaVg+wg==", 162 | "engines": { 163 | "node": ">=18.14.1" 164 | }, 165 | "peerDependencies": { 166 | "hono": "^4" 167 | } 168 | }, 169 | "node_modules/@hono/node-ws": { 170 | "version": "1.1.0", 171 | "resolved": "https://registry.npmjs.org/@hono/node-ws/-/node-ws-1.1.0.tgz", 172 | "integrity": "sha512-uHaz1EPguJqsUmA+Jmhdi/DTRAMs2Fvcy7qno9E48rlK3WBtyGQw4u4DKlc+o18Nh1DGz2oA1n9hCzEyhVBeLw==", 173 | "dependencies": { 174 | "ws": "^8.17.0" 175 | }, 176 | "engines": { 177 | "node": ">=18.14.1" 178 | }, 179 | "peerDependencies": { 180 | "@hono/node-server": "^1.11.1", 181 | "hono": "^4.6.0" 182 | } 183 | }, 184 | "node_modules/@noble/hashes": { 185 | "version": "1.6.1", 186 | "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.6.1.tgz", 187 | "integrity": "sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w==", 188 | "engines": { 189 | "node": "^14.21.3 || >=16" 190 | }, 191 | "funding": { 192 | "url": "https://paulmillr.com/funding/" 193 | } 194 | }, 195 | "node_modules/@openrouter/ai-sdk-provider": { 196 | "version": "0.4.5", 197 | "resolved": "https://registry.npmjs.org/@openrouter/ai-sdk-provider/-/ai-sdk-provider-0.4.5.tgz", 198 | "integrity": "sha512-gbCOcSjNhyWlLHyYZX2rIFnpJi3C2RXNyyzJj+d6pMRfTS/mdvEEOsU66KxK9H8Qju2i9YRLOn/FdQT26K7bIQ==", 199 | "dependencies": { 200 | "@ai-sdk/provider": "1.0.9", 201 | "@ai-sdk/provider-utils": "2.1.10" 202 | }, 203 | "engines": { 204 | "node": ">=18" 205 | }, 206 | "peerDependencies": { 207 | "zod": "^3.0.0" 208 | } 209 | }, 210 | "node_modules/@portkey-ai/gateway": { 211 | "version": "1.9.15", 212 | "resolved": "https://registry.npmjs.org/@portkey-ai/gateway/-/gateway-1.9.15.tgz", 213 | "integrity": "sha512-dlcAdfIdlZsP8AZx8i14SjJAMih2gJR1Mn3cycojDv/DHrhTDKibUx/F/N07DDNaPCBxbvFWQTIK9W49LWrCwg==", 214 | "hasInstallScript": true, 215 | "dependencies": { 216 | "@aws-crypto/sha256-js": "^5.2.0", 217 | "@cfworker/json-schema": "^4.0.3", 218 | "@hono/node-server": "^1.3.3", 219 | "@hono/node-ws": "^1.0.4", 220 | "@portkey-ai/mustache": "^2.1.2", 221 | "@smithy/signature-v4": "^2.1.1", 222 | "@types/mustache": "^4.2.5", 223 | "async-retry": "^1.3.3", 224 | "avsc": "^5.7.7", 225 | "hono": "^4.6.10", 226 | "patch-package": "^8.0.0", 227 | "ws": "^8.18.0", 228 | "zod": "^3.22.4" 229 | }, 230 | "bin": { 231 | "gateway": "build/start-server.js" 232 | } 233 | }, 234 | "node_modules/@portkey-ai/mustache": { 235 | "version": "2.1.2", 236 | "resolved": "https://registry.npmjs.org/@portkey-ai/mustache/-/mustache-2.1.2.tgz", 237 | "integrity": "sha512-0Ood+f2PPQIwBMVzRUKS/iKzQy61OghUBcp4CkcYVgWpIc3FXbGFUqzRqcOXOAiD34mZ1AKUPlMmPXXYsuA9fA==" 238 | }, 239 | "node_modules/@roamhq/wrtc": { 240 | "version": "0.8.0", 241 | "resolved": "https://registry.npmjs.org/@roamhq/wrtc/-/wrtc-0.8.0.tgz", 242 | "integrity": "sha512-C0V/nqc4/2xzORI5qa4mIeN/8UO3ywN1kInrJ9u6GljFx0D18JMUJEqe8yYHa61RrEeoWN3PKdW++k8TocSx/A==", 243 | "optionalDependencies": { 244 | "@roamhq/wrtc-darwin-arm64": "0.8.0", 245 | "@roamhq/wrtc-darwin-x64": "0.8.0", 246 | "@roamhq/wrtc-linux-arm64": "0.8.1", 247 | "@roamhq/wrtc-linux-x64": "0.8.1", 248 | "@roamhq/wrtc-win32-x64": "0.8.0", 249 | "domexception": "^4.0.0" 250 | } 251 | }, 252 | "node_modules/@roamhq/wrtc-darwin-arm64": { 253 | "version": "0.8.0", 254 | "resolved": "https://registry.npmjs.org/@roamhq/wrtc-darwin-arm64/-/wrtc-darwin-arm64-0.8.0.tgz", 255 | "integrity": "sha512-OtV2KWO7zOG3L8TF3KCt9aucynVCD/ww2xeXXgg+FLkya3ca0uzehN8EQJ3BL4tkInksbFJ2ssyu9cehfJ3ZuA==", 256 | "cpu": [ 257 | "arm64" 258 | ], 259 | "optional": true, 260 | "os": [ 261 | "darwin" 262 | ] 263 | }, 264 | "node_modules/@roamhq/wrtc-darwin-x64": { 265 | "version": "0.8.0", 266 | "resolved": "https://registry.npmjs.org/@roamhq/wrtc-darwin-x64/-/wrtc-darwin-x64-0.8.0.tgz", 267 | "integrity": "sha512-VY7Vzt/SDDDCpW//h8GW9bOZrOr8gWXPZVD9473ypl4jyBIoO57yyLbHzd1G0vBUkS6szsHlQCz1WwpI30YL+g==", 268 | "cpu": [ 269 | "x64" 270 | ], 271 | "optional": true, 272 | "os": [ 273 | "darwin" 274 | ] 275 | }, 276 | "node_modules/@roamhq/wrtc-linux-arm64": { 277 | "version": "0.8.1", 278 | "resolved": "https://registry.npmjs.org/@roamhq/wrtc-linux-arm64/-/wrtc-linux-arm64-0.8.1.tgz", 279 | "integrity": "sha512-FBJLLazlWkGQUXaokC/rTbrUQbb0CNFYry52fZGstufrGLTWu+g4HcwXdVvxh1tnVtVMvkQGk+mlOL52sCxw0A==", 280 | "cpu": [ 281 | "arm64" 282 | ], 283 | "optional": true, 284 | "os": [ 285 | "linux" 286 | ] 287 | }, 288 | "node_modules/@roamhq/wrtc-linux-x64": { 289 | "version": "0.8.1", 290 | "resolved": "https://registry.npmjs.org/@roamhq/wrtc-linux-x64/-/wrtc-linux-x64-0.8.1.tgz", 291 | "integrity": "sha512-I9oWG7b4uvWO1IOR/aF34n+ID6TKVuSs0jd19h5KdhfRtw7FFh9xxuwN9rONPxLVa6fS0q+MCZgAf8Scz89L8Q==", 292 | "cpu": [ 293 | "x64" 294 | ], 295 | "optional": true, 296 | "os": [ 297 | "linux" 298 | ] 299 | }, 300 | "node_modules/@roamhq/wrtc-win32-x64": { 301 | "version": "0.8.0", 302 | "resolved": "https://registry.npmjs.org/@roamhq/wrtc-win32-x64/-/wrtc-win32-x64-0.8.0.tgz", 303 | "integrity": "sha512-R2fxl41BLWPiP4eaTHGLzbbVvRjx1mV/OsgINCvawO7Hwz5Zx9I45+Fhrw3hd4n5amIeSG9VIF7Kz8eeTFXTGQ==", 304 | "cpu": [ 305 | "x64" 306 | ], 307 | "optional": true, 308 | "os": [ 309 | "win32" 310 | ] 311 | }, 312 | "node_modules/@sinclair/typebox": { 313 | "version": "0.32.35", 314 | "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.32.35.tgz", 315 | "integrity": "sha512-Ul3YyOTU++to8cgNkttakC0dWvpERr6RYoHO2W47DLbFvrwBDJUY31B1sImH6JZSYc4Kt4PyHtoPNu+vL2r2dA==" 316 | }, 317 | "node_modules/@sindresorhus/is": { 318 | "version": "4.6.0", 319 | "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", 320 | "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", 321 | "engines": { 322 | "node": ">=10" 323 | }, 324 | "funding": { 325 | "url": "https://github.com/sindresorhus/is?sponsor=1" 326 | } 327 | }, 328 | "node_modules/@smithy/is-array-buffer": { 329 | "version": "2.2.0", 330 | "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", 331 | "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", 332 | "dependencies": { 333 | "tslib": "^2.6.2" 334 | }, 335 | "engines": { 336 | "node": ">=14.0.0" 337 | } 338 | }, 339 | "node_modules/@smithy/signature-v4": { 340 | "version": "2.3.0", 341 | "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-2.3.0.tgz", 342 | "integrity": "sha512-ui/NlpILU+6HAQBfJX8BBsDXuKSNrjTSuOYArRblcrErwKFutjrCNb/OExfVRyj9+26F9J+ZmfWT+fKWuDrH3Q==", 343 | "dependencies": { 344 | "@smithy/is-array-buffer": "^2.2.0", 345 | "@smithy/types": "^2.12.0", 346 | "@smithy/util-hex-encoding": "^2.2.0", 347 | "@smithy/util-middleware": "^2.2.0", 348 | "@smithy/util-uri-escape": "^2.2.0", 349 | "@smithy/util-utf8": "^2.3.0", 350 | "tslib": "^2.6.2" 351 | }, 352 | "engines": { 353 | "node": ">=14.0.0" 354 | } 355 | }, 356 | "node_modules/@smithy/signature-v4/node_modules/@smithy/types": { 357 | "version": "2.12.0", 358 | "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz", 359 | "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==", 360 | "dependencies": { 361 | "tslib": "^2.6.2" 362 | }, 363 | "engines": { 364 | "node": ">=14.0.0" 365 | } 366 | }, 367 | "node_modules/@smithy/types": { 368 | "version": "4.1.0", 369 | "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.1.0.tgz", 370 | "integrity": "sha512-enhjdwp4D7CXmwLtD6zbcDMbo6/T6WtuuKCY49Xxc6OMOmUWlBEBDREsxxgV2LIdeQPW756+f97GzcgAwp3iLw==", 371 | "dependencies": { 372 | "tslib": "^2.6.2" 373 | }, 374 | "engines": { 375 | "node": ">=18.0.0" 376 | } 377 | }, 378 | "node_modules/@smithy/util-buffer-from": { 379 | "version": "2.2.0", 380 | "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", 381 | "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", 382 | "dependencies": { 383 | "@smithy/is-array-buffer": "^2.2.0", 384 | "tslib": "^2.6.2" 385 | }, 386 | "engines": { 387 | "node": ">=14.0.0" 388 | } 389 | }, 390 | "node_modules/@smithy/util-hex-encoding": { 391 | "version": "2.2.0", 392 | "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-2.2.0.tgz", 393 | "integrity": "sha512-7iKXR+/4TpLK194pVjKiasIyqMtTYJsgKgM242Y9uzt5dhHnUDvMNb+3xIhRJ9QhvqGii/5cRUt4fJn3dtXNHQ==", 394 | "dependencies": { 395 | "tslib": "^2.6.2" 396 | }, 397 | "engines": { 398 | "node": ">=14.0.0" 399 | } 400 | }, 401 | "node_modules/@smithy/util-middleware": { 402 | "version": "2.2.0", 403 | "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-2.2.0.tgz", 404 | "integrity": "sha512-L1qpleXf9QD6LwLCJ5jddGkgWyuSvWBkJwWAZ6kFkdifdso+sk3L3O1HdmPvCdnCK3IS4qWyPxev01QMnfHSBw==", 405 | "dependencies": { 406 | "@smithy/types": "^2.12.0", 407 | "tslib": "^2.6.2" 408 | }, 409 | "engines": { 410 | "node": ">=14.0.0" 411 | } 412 | }, 413 | "node_modules/@smithy/util-middleware/node_modules/@smithy/types": { 414 | "version": "2.12.0", 415 | "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz", 416 | "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==", 417 | "dependencies": { 418 | "tslib": "^2.6.2" 419 | }, 420 | "engines": { 421 | "node": ">=14.0.0" 422 | } 423 | }, 424 | "node_modules/@smithy/util-uri-escape": { 425 | "version": "2.2.0", 426 | "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-2.2.0.tgz", 427 | "integrity": "sha512-jtmJMyt1xMD/d8OtbVJ2gFZOSKc+ueYJZPW20ULW1GOp/q/YIM0wNh+u8ZFao9UaIGz4WoPW8hC64qlWLIfoDA==", 428 | "dependencies": { 429 | "tslib": "^2.6.2" 430 | }, 431 | "engines": { 432 | "node": ">=14.0.0" 433 | } 434 | }, 435 | "node_modules/@smithy/util-utf8": { 436 | "version": "2.3.0", 437 | "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", 438 | "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", 439 | "dependencies": { 440 | "@smithy/util-buffer-from": "^2.2.0", 441 | "tslib": "^2.6.2" 442 | }, 443 | "engines": { 444 | "node": ">=14.0.0" 445 | } 446 | }, 447 | "node_modules/@types/minimist": { 448 | "version": "1.2.5", 449 | "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", 450 | "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", 451 | "dev": true 452 | }, 453 | "node_modules/@types/mustache": { 454 | "version": "4.2.5", 455 | "resolved": "https://registry.npmjs.org/@types/mustache/-/mustache-4.2.5.tgz", 456 | "integrity": "sha512-PLwiVvTBg59tGFL/8VpcGvqOu3L4OuveNvPi0EYbWchRdEVP++yRUXJPFl+CApKEq13017/4Nf7aQ5lTtHUNsA==" 457 | }, 458 | "node_modules/@types/node": { 459 | "version": "18.19.76", 460 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.76.tgz", 461 | "integrity": "sha512-yvR7Q9LdPz2vGpmpJX5LolrgRdWvB67MJKDPSgIIzpFbaf9a1j/f5DnLp5VDyHGMR0QZHlTr1afsD87QCXFHKw==", 462 | "dependencies": { 463 | "undici-types": "~5.26.4" 464 | } 465 | }, 466 | "node_modules/@types/node-fetch": { 467 | "version": "2.6.12", 468 | "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz", 469 | "integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==", 470 | "dependencies": { 471 | "@types/node": "*", 472 | "form-data": "^4.0.0" 473 | } 474 | }, 475 | "node_modules/@yarnpkg/lockfile": { 476 | "version": "1.1.0", 477 | "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", 478 | "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==" 479 | }, 480 | "node_modules/abort-controller": { 481 | "version": "3.0.0", 482 | "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", 483 | "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", 484 | "dependencies": { 485 | "event-target-shim": "^5.0.0" 486 | }, 487 | "engines": { 488 | "node": ">=6.5" 489 | } 490 | }, 491 | "node_modules/agent-base": { 492 | "version": "7.1.3", 493 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", 494 | "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", 495 | "engines": { 496 | "node": ">= 14" 497 | } 498 | }, 499 | "node_modules/agent-twitter-client-taelin-fork": { 500 | "version": "0.0.26", 501 | "resolved": "https://registry.npmjs.org/agent-twitter-client-taelin-fork/-/agent-twitter-client-taelin-fork-0.0.26.tgz", 502 | "integrity": "sha512-vPKNapbtS8lmSkHWebcmM11oN2gFeedUJfmtn0AqS13i/LTbKIcyRzxQqw1aNSBDNR1VCrA/l7SbW1Ld08Og3g==", 503 | "dependencies": { 504 | "@roamhq/wrtc": "^0.8.0", 505 | "@sinclair/typebox": "^0.32.20", 506 | "headers-polyfill": "^3.1.2", 507 | "json-stable-stringify": "^1.0.2", 508 | "otpauth": "^9.2.2", 509 | "set-cookie-parser": "^2.6.0", 510 | "tough-cookie": "^5.1.1", 511 | "twitter-api-v2": "^1.18.2", 512 | "undici": "^7.1.1", 513 | "undici-types": "^7.2.0", 514 | "ws": "^8.18.0" 515 | } 516 | }, 517 | "node_modules/agent-twitter-client-taelin-fork/node_modules/undici-types": { 518 | "version": "7.3.0", 519 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.3.0.tgz", 520 | "integrity": "sha512-z2pHpkN2BEJl3QlQo0GtfGCyuhuBbWX60vzGwyn7ex/seM2UkvyGEfEV0Qb9pXc5StNfcJpsstgaf2YTEJa63Q==" 521 | }, 522 | "node_modules/agentkeepalive": { 523 | "version": "4.6.0", 524 | "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", 525 | "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", 526 | "dependencies": { 527 | "humanize-ms": "^1.2.1" 528 | }, 529 | "engines": { 530 | "node": ">= 8.0.0" 531 | } 532 | }, 533 | "node_modules/ansi-colors": { 534 | "version": "4.1.3", 535 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", 536 | "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", 537 | "engines": { 538 | "node": ">=6" 539 | } 540 | }, 541 | "node_modules/ansi-styles": { 542 | "version": "4.3.0", 543 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 544 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 545 | "dependencies": { 546 | "color-convert": "^2.0.1" 547 | }, 548 | "engines": { 549 | "node": ">=8" 550 | }, 551 | "funding": { 552 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 553 | } 554 | }, 555 | "node_modules/apify-client": { 556 | "version": "2.12.2", 557 | "resolved": "https://registry.npmjs.org/apify-client/-/apify-client-2.12.2.tgz", 558 | "integrity": "sha512-+eSexDukVso58MQ8pOJj67mnaDkexH80VJs0/stfM8yNSUKMa/BIIdbG3rX8axjpTtT3UzpPgMIz6qh8inxFCQ==", 559 | "dependencies": { 560 | "@apify/consts": "^2.40.0", 561 | "@apify/log": "^2.2.6", 562 | "@crawlee/types": "^3.3.0", 563 | "agentkeepalive": "^4.2.1", 564 | "async-retry": "^1.3.3", 565 | "axios": "^1.6.7", 566 | "content-type": "^1.0.5", 567 | "ow": "^0.28.2", 568 | "tslib": "^2.5.0", 569 | "type-fest": "^4.0.0" 570 | } 571 | }, 572 | "node_modules/async-retry": { 573 | "version": "1.3.3", 574 | "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", 575 | "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", 576 | "dependencies": { 577 | "retry": "0.13.1" 578 | } 579 | }, 580 | "node_modules/asynckit": { 581 | "version": "0.4.0", 582 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 583 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" 584 | }, 585 | "node_modules/at-least-node": { 586 | "version": "1.0.0", 587 | "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", 588 | "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", 589 | "engines": { 590 | "node": ">= 4.0.0" 591 | } 592 | }, 593 | "node_modules/avsc": { 594 | "version": "5.7.7", 595 | "resolved": "https://registry.npmjs.org/avsc/-/avsc-5.7.7.tgz", 596 | "integrity": "sha512-9cYNccliXZDByFsFliVwk5GvTq058Fj513CiR4E60ndDwmuXzTJEp/Bp8FyuRmGyYupLjHLs+JA9/CBoVS4/NQ==", 597 | "engines": { 598 | "node": ">=0.11" 599 | } 600 | }, 601 | "node_modules/axios": { 602 | "version": "1.7.9", 603 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", 604 | "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", 605 | "dependencies": { 606 | "follow-redirects": "^1.15.6", 607 | "form-data": "^4.0.0", 608 | "proxy-from-env": "^1.1.0" 609 | } 610 | }, 611 | "node_modules/balanced-match": { 612 | "version": "1.0.2", 613 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 614 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 615 | }, 616 | "node_modules/base64-js": { 617 | "version": "1.5.1", 618 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 619 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 620 | "funding": [ 621 | { 622 | "type": "github", 623 | "url": "https://github.com/sponsors/feross" 624 | }, 625 | { 626 | "type": "patreon", 627 | "url": "https://www.patreon.com/feross" 628 | }, 629 | { 630 | "type": "consulting", 631 | "url": "https://feross.org/support" 632 | } 633 | ] 634 | }, 635 | "node_modules/bignumber.js": { 636 | "version": "9.1.2", 637 | "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", 638 | "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==", 639 | "engines": { 640 | "node": "*" 641 | } 642 | }, 643 | "node_modules/brace-expansion": { 644 | "version": "1.1.11", 645 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 646 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 647 | "dependencies": { 648 | "balanced-match": "^1.0.0", 649 | "concat-map": "0.0.1" 650 | } 651 | }, 652 | "node_modules/braces": { 653 | "version": "3.0.3", 654 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 655 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 656 | "dependencies": { 657 | "fill-range": "^7.1.1" 658 | }, 659 | "engines": { 660 | "node": ">=8" 661 | } 662 | }, 663 | "node_modules/buffer-equal-constant-time": { 664 | "version": "1.0.1", 665 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", 666 | "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" 667 | }, 668 | "node_modules/call-bind": { 669 | "version": "1.0.8", 670 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", 671 | "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", 672 | "dependencies": { 673 | "call-bind-apply-helpers": "^1.0.0", 674 | "es-define-property": "^1.0.0", 675 | "get-intrinsic": "^1.2.4", 676 | "set-function-length": "^1.2.2" 677 | }, 678 | "engines": { 679 | "node": ">= 0.4" 680 | }, 681 | "funding": { 682 | "url": "https://github.com/sponsors/ljharb" 683 | } 684 | }, 685 | "node_modules/call-bind-apply-helpers": { 686 | "version": "1.0.2", 687 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", 688 | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", 689 | "dependencies": { 690 | "es-errors": "^1.3.0", 691 | "function-bind": "^1.1.2" 692 | }, 693 | "engines": { 694 | "node": ">= 0.4" 695 | } 696 | }, 697 | "node_modules/call-bound": { 698 | "version": "1.0.3", 699 | "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", 700 | "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", 701 | "dependencies": { 702 | "call-bind-apply-helpers": "^1.0.1", 703 | "get-intrinsic": "^1.2.6" 704 | }, 705 | "engines": { 706 | "node": ">= 0.4" 707 | }, 708 | "funding": { 709 | "url": "https://github.com/sponsors/ljharb" 710 | } 711 | }, 712 | "node_modules/callsites": { 713 | "version": "3.1.0", 714 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 715 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 716 | "engines": { 717 | "node": ">=6" 718 | } 719 | }, 720 | "node_modules/chalk": { 721 | "version": "4.1.2", 722 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", 723 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 724 | "dependencies": { 725 | "ansi-styles": "^4.1.0", 726 | "supports-color": "^7.1.0" 727 | }, 728 | "engines": { 729 | "node": ">=10" 730 | }, 731 | "funding": { 732 | "url": "https://github.com/chalk/chalk?sponsor=1" 733 | } 734 | }, 735 | "node_modules/ci-info": { 736 | "version": "3.9.0", 737 | "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", 738 | "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", 739 | "funding": [ 740 | { 741 | "type": "github", 742 | "url": "https://github.com/sponsors/sibiraj-s" 743 | } 744 | ], 745 | "engines": { 746 | "node": ">=8" 747 | } 748 | }, 749 | "node_modules/color-convert": { 750 | "version": "2.0.1", 751 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 752 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 753 | "dependencies": { 754 | "color-name": "~1.1.4" 755 | }, 756 | "engines": { 757 | "node": ">=7.0.0" 758 | } 759 | }, 760 | "node_modules/color-name": { 761 | "version": "1.1.4", 762 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 763 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 764 | }, 765 | "node_modules/combined-stream": { 766 | "version": "1.0.8", 767 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 768 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 769 | "dependencies": { 770 | "delayed-stream": "~1.0.0" 771 | }, 772 | "engines": { 773 | "node": ">= 0.8" 774 | } 775 | }, 776 | "node_modules/commander": { 777 | "version": "13.1.0", 778 | "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", 779 | "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", 780 | "engines": { 781 | "node": ">=18" 782 | } 783 | }, 784 | "node_modules/concat-map": { 785 | "version": "0.0.1", 786 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 787 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" 788 | }, 789 | "node_modules/content-type": { 790 | "version": "1.0.5", 791 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 792 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 793 | "engines": { 794 | "node": ">= 0.6" 795 | } 796 | }, 797 | "node_modules/cross-spawn": { 798 | "version": "7.0.6", 799 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 800 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 801 | "dependencies": { 802 | "path-key": "^3.1.0", 803 | "shebang-command": "^2.0.0", 804 | "which": "^2.0.1" 805 | }, 806 | "engines": { 807 | "node": ">= 8" 808 | } 809 | }, 810 | "node_modules/debug": { 811 | "version": "4.4.0", 812 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 813 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 814 | "dependencies": { 815 | "ms": "^2.1.3" 816 | }, 817 | "engines": { 818 | "node": ">=6.0" 819 | }, 820 | "peerDependenciesMeta": { 821 | "supports-color": { 822 | "optional": true 823 | } 824 | } 825 | }, 826 | "node_modules/define-data-property": { 827 | "version": "1.1.4", 828 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", 829 | "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", 830 | "dependencies": { 831 | "es-define-property": "^1.0.0", 832 | "es-errors": "^1.3.0", 833 | "gopd": "^1.0.1" 834 | }, 835 | "engines": { 836 | "node": ">= 0.4" 837 | }, 838 | "funding": { 839 | "url": "https://github.com/sponsors/ljharb" 840 | } 841 | }, 842 | "node_modules/delayed-stream": { 843 | "version": "1.0.0", 844 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 845 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 846 | "engines": { 847 | "node": ">=0.4.0" 848 | } 849 | }, 850 | "node_modules/domexception": { 851 | "version": "4.0.0", 852 | "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", 853 | "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", 854 | "deprecated": "Use your platform's native DOMException instead", 855 | "optional": true, 856 | "dependencies": { 857 | "webidl-conversions": "^7.0.0" 858 | }, 859 | "engines": { 860 | "node": ">=12" 861 | } 862 | }, 863 | "node_modules/dot-prop": { 864 | "version": "6.0.1", 865 | "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", 866 | "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", 867 | "dependencies": { 868 | "is-obj": "^2.0.0" 869 | }, 870 | "engines": { 871 | "node": ">=10" 872 | }, 873 | "funding": { 874 | "url": "https://github.com/sponsors/sindresorhus" 875 | } 876 | }, 877 | "node_modules/dotenv": { 878 | "version": "16.4.7", 879 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", 880 | "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", 881 | "engines": { 882 | "node": ">=12" 883 | }, 884 | "funding": { 885 | "url": "https://dotenvx.com" 886 | } 887 | }, 888 | "node_modules/dunder-proto": { 889 | "version": "1.0.1", 890 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", 891 | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", 892 | "dependencies": { 893 | "call-bind-apply-helpers": "^1.0.1", 894 | "es-errors": "^1.3.0", 895 | "gopd": "^1.2.0" 896 | }, 897 | "engines": { 898 | "node": ">= 0.4" 899 | } 900 | }, 901 | "node_modules/ecdsa-sig-formatter": { 902 | "version": "1.0.11", 903 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", 904 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", 905 | "dependencies": { 906 | "safe-buffer": "^5.0.1" 907 | } 908 | }, 909 | "node_modules/es-define-property": { 910 | "version": "1.0.1", 911 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", 912 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", 913 | "engines": { 914 | "node": ">= 0.4" 915 | } 916 | }, 917 | "node_modules/es-errors": { 918 | "version": "1.3.0", 919 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 920 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 921 | "engines": { 922 | "node": ">= 0.4" 923 | } 924 | }, 925 | "node_modules/es-object-atoms": { 926 | "version": "1.1.1", 927 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", 928 | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", 929 | "dependencies": { 930 | "es-errors": "^1.3.0" 931 | }, 932 | "engines": { 933 | "node": ">= 0.4" 934 | } 935 | }, 936 | "node_modules/es-set-tostringtag": { 937 | "version": "2.1.0", 938 | "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", 939 | "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", 940 | "dependencies": { 941 | "es-errors": "^1.3.0", 942 | "get-intrinsic": "^1.2.6", 943 | "has-tostringtag": "^1.0.2", 944 | "hasown": "^2.0.2" 945 | }, 946 | "engines": { 947 | "node": ">= 0.4" 948 | } 949 | }, 950 | "node_modules/event-target-shim": { 951 | "version": "5.0.1", 952 | "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", 953 | "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", 954 | "engines": { 955 | "node": ">=6" 956 | } 957 | }, 958 | "node_modules/eventsource-parser": { 959 | "version": "3.0.1", 960 | "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.1.tgz", 961 | "integrity": "sha512-VARTJ9CYeuQYb0pZEPbzi740OWFgpHe7AYJ2WFZVnUDUQp5Dk2yJUgF36YsZ81cOyxT0QxmXD2EQpapAouzWVA==", 962 | "engines": { 963 | "node": ">=18.0.0" 964 | } 965 | }, 966 | "node_modules/extend": { 967 | "version": "3.0.2", 968 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 969 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 970 | }, 971 | "node_modules/fill-range": { 972 | "version": "7.1.1", 973 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 974 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 975 | "dependencies": { 976 | "to-regex-range": "^5.0.1" 977 | }, 978 | "engines": { 979 | "node": ">=8" 980 | } 981 | }, 982 | "node_modules/find-yarn-workspace-root": { 983 | "version": "2.0.0", 984 | "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", 985 | "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", 986 | "dependencies": { 987 | "micromatch": "^4.0.2" 988 | } 989 | }, 990 | "node_modules/follow-redirects": { 991 | "version": "1.15.9", 992 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", 993 | "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", 994 | "funding": [ 995 | { 996 | "type": "individual", 997 | "url": "https://github.com/sponsors/RubenVerborgh" 998 | } 999 | ], 1000 | "engines": { 1001 | "node": ">=4.0" 1002 | }, 1003 | "peerDependenciesMeta": { 1004 | "debug": { 1005 | "optional": true 1006 | } 1007 | } 1008 | }, 1009 | "node_modules/form-data": { 1010 | "version": "4.0.2", 1011 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", 1012 | "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", 1013 | "dependencies": { 1014 | "asynckit": "^0.4.0", 1015 | "combined-stream": "^1.0.8", 1016 | "es-set-tostringtag": "^2.1.0", 1017 | "mime-types": "^2.1.12" 1018 | }, 1019 | "engines": { 1020 | "node": ">= 6" 1021 | } 1022 | }, 1023 | "node_modules/form-data-encoder": { 1024 | "version": "1.7.2", 1025 | "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", 1026 | "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==" 1027 | }, 1028 | "node_modules/formdata-node": { 1029 | "version": "4.4.1", 1030 | "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", 1031 | "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", 1032 | "dependencies": { 1033 | "node-domexception": "1.0.0", 1034 | "web-streams-polyfill": "4.0.0-beta.3" 1035 | }, 1036 | "engines": { 1037 | "node": ">= 12.20" 1038 | } 1039 | }, 1040 | "node_modules/formdata-node/node_modules/web-streams-polyfill": { 1041 | "version": "4.0.0-beta.3", 1042 | "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", 1043 | "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", 1044 | "engines": { 1045 | "node": ">= 14" 1046 | } 1047 | }, 1048 | "node_modules/fs-extra": { 1049 | "version": "9.1.0", 1050 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", 1051 | "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", 1052 | "dependencies": { 1053 | "at-least-node": "^1.0.0", 1054 | "graceful-fs": "^4.2.0", 1055 | "jsonfile": "^6.0.1", 1056 | "universalify": "^2.0.0" 1057 | }, 1058 | "engines": { 1059 | "node": ">=10" 1060 | } 1061 | }, 1062 | "node_modules/fs.realpath": { 1063 | "version": "1.0.0", 1064 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1065 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" 1066 | }, 1067 | "node_modules/function-bind": { 1068 | "version": "1.1.2", 1069 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 1070 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 1071 | "funding": { 1072 | "url": "https://github.com/sponsors/ljharb" 1073 | } 1074 | }, 1075 | "node_modules/gateway": { 1076 | "version": "1.0.0", 1077 | "resolved": "https://registry.npmjs.org/gateway/-/gateway-1.0.0.tgz", 1078 | "integrity": "sha512-+yl70ZpYuhWDLmI6DPolQq/nqbst0Gb2ZHsRlEu9QOMoS4LbIIwWxubfgnbHhdQIhDyveHXd1f0vU8UDgYblfA==" 1079 | }, 1080 | "node_modules/gaxios": { 1081 | "version": "6.7.1", 1082 | "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", 1083 | "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", 1084 | "dependencies": { 1085 | "extend": "^3.0.2", 1086 | "https-proxy-agent": "^7.0.1", 1087 | "is-stream": "^2.0.0", 1088 | "node-fetch": "^2.6.9", 1089 | "uuid": "^9.0.1" 1090 | }, 1091 | "engines": { 1092 | "node": ">=14" 1093 | } 1094 | }, 1095 | "node_modules/gcp-metadata": { 1096 | "version": "6.1.1", 1097 | "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", 1098 | "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", 1099 | "dependencies": { 1100 | "gaxios": "^6.1.1", 1101 | "google-logging-utils": "^0.0.2", 1102 | "json-bigint": "^1.0.0" 1103 | }, 1104 | "engines": { 1105 | "node": ">=14" 1106 | } 1107 | }, 1108 | "node_modules/get-intrinsic": { 1109 | "version": "1.3.0", 1110 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", 1111 | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", 1112 | "dependencies": { 1113 | "call-bind-apply-helpers": "^1.0.2", 1114 | "es-define-property": "^1.0.1", 1115 | "es-errors": "^1.3.0", 1116 | "es-object-atoms": "^1.1.1", 1117 | "function-bind": "^1.1.2", 1118 | "get-proto": "^1.0.1", 1119 | "gopd": "^1.2.0", 1120 | "has-symbols": "^1.1.0", 1121 | "hasown": "^2.0.2", 1122 | "math-intrinsics": "^1.1.0" 1123 | }, 1124 | "engines": { 1125 | "node": ">= 0.4" 1126 | }, 1127 | "funding": { 1128 | "url": "https://github.com/sponsors/ljharb" 1129 | } 1130 | }, 1131 | "node_modules/get-proto": { 1132 | "version": "1.0.1", 1133 | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", 1134 | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", 1135 | "dependencies": { 1136 | "dunder-proto": "^1.0.1", 1137 | "es-object-atoms": "^1.0.0" 1138 | }, 1139 | "engines": { 1140 | "node": ">= 0.4" 1141 | } 1142 | }, 1143 | "node_modules/glob": { 1144 | "version": "7.2.3", 1145 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 1146 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 1147 | "deprecated": "Glob versions prior to v9 are no longer supported", 1148 | "dependencies": { 1149 | "fs.realpath": "^1.0.0", 1150 | "inflight": "^1.0.4", 1151 | "inherits": "2", 1152 | "minimatch": "^3.1.1", 1153 | "once": "^1.3.0", 1154 | "path-is-absolute": "^1.0.0" 1155 | }, 1156 | "engines": { 1157 | "node": "*" 1158 | }, 1159 | "funding": { 1160 | "url": "https://github.com/sponsors/isaacs" 1161 | } 1162 | }, 1163 | "node_modules/google-auth-library": { 1164 | "version": "9.15.1", 1165 | "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.1.tgz", 1166 | "integrity": "sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==", 1167 | "dependencies": { 1168 | "base64-js": "^1.3.0", 1169 | "ecdsa-sig-formatter": "^1.0.11", 1170 | "gaxios": "^6.1.1", 1171 | "gcp-metadata": "^6.1.0", 1172 | "gtoken": "^7.0.0", 1173 | "jws": "^4.0.0" 1174 | }, 1175 | "engines": { 1176 | "node": ">=14" 1177 | } 1178 | }, 1179 | "node_modules/google-logging-utils": { 1180 | "version": "0.0.2", 1181 | "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", 1182 | "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", 1183 | "engines": { 1184 | "node": ">=14" 1185 | } 1186 | }, 1187 | "node_modules/googleapis": { 1188 | "version": "148.0.0", 1189 | "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-148.0.0.tgz", 1190 | "integrity": "sha512-8PDG5VItm6E1TdZWDqtRrUJSlBcNwz0/MwCa6AL81y/RxPGXJRUwKqGZfCoVX1ZBbfr3I4NkDxBmeTyOAZSWqw==", 1191 | "dependencies": { 1192 | "google-auth-library": "^9.0.0", 1193 | "googleapis-common": "^7.0.0" 1194 | }, 1195 | "engines": { 1196 | "node": ">=14.0.0" 1197 | } 1198 | }, 1199 | "node_modules/googleapis-common": { 1200 | "version": "7.2.0", 1201 | "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-7.2.0.tgz", 1202 | "integrity": "sha512-/fhDZEJZvOV3X5jmD+fKxMqma5q2Q9nZNSF3kn1F18tpxmA86BcTxAGBQdM0N89Z3bEaIs+HVznSmFJEAmMTjA==", 1203 | "dependencies": { 1204 | "extend": "^3.0.2", 1205 | "gaxios": "^6.0.3", 1206 | "google-auth-library": "^9.7.0", 1207 | "qs": "^6.7.0", 1208 | "url-template": "^2.0.8", 1209 | "uuid": "^9.0.0" 1210 | }, 1211 | "engines": { 1212 | "node": ">=14.0.0" 1213 | } 1214 | }, 1215 | "node_modules/gopd": { 1216 | "version": "1.2.0", 1217 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", 1218 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", 1219 | "engines": { 1220 | "node": ">= 0.4" 1221 | }, 1222 | "funding": { 1223 | "url": "https://github.com/sponsors/ljharb" 1224 | } 1225 | }, 1226 | "node_modules/gpt-tokenizer": { 1227 | "version": "2.9.0", 1228 | "resolved": "https://registry.npmjs.org/gpt-tokenizer/-/gpt-tokenizer-2.9.0.tgz", 1229 | "integrity": "sha512-YSpexBL/k4bfliAzMrRqn3M6+it02LutVyhVpDeMKrC/O9+pCe/5s8U2hYKa2vFLD5/vHhsKc8sOn/qGqII8Kg==" 1230 | }, 1231 | "node_modules/graceful-fs": { 1232 | "version": "4.2.11", 1233 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 1234 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" 1235 | }, 1236 | "node_modules/groq-sdk": { 1237 | "version": "0.19.0", 1238 | "resolved": "https://registry.npmjs.org/groq-sdk/-/groq-sdk-0.19.0.tgz", 1239 | "integrity": "sha512-vdh5h7ORvwvOvutA80dKF81b0gPWHxu6K/GOJBOM0n6p6CSqAVLhFfeS79Ef0j/yCycDR09jqY7jkYz9dLiS6w==", 1240 | "dependencies": { 1241 | "@types/node": "^18.11.18", 1242 | "@types/node-fetch": "^2.6.4", 1243 | "abort-controller": "^3.0.0", 1244 | "agentkeepalive": "^4.2.1", 1245 | "form-data-encoder": "1.7.2", 1246 | "formdata-node": "^4.3.2", 1247 | "node-fetch": "^2.6.7" 1248 | } 1249 | }, 1250 | "node_modules/gtoken": { 1251 | "version": "7.1.0", 1252 | "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz", 1253 | "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==", 1254 | "dependencies": { 1255 | "gaxios": "^6.0.0", 1256 | "jws": "^4.0.0" 1257 | }, 1258 | "engines": { 1259 | "node": ">=14.0.0" 1260 | } 1261 | }, 1262 | "node_modules/has-flag": { 1263 | "version": "4.0.0", 1264 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1265 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1266 | "engines": { 1267 | "node": ">=8" 1268 | } 1269 | }, 1270 | "node_modules/has-property-descriptors": { 1271 | "version": "1.0.2", 1272 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", 1273 | "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", 1274 | "dependencies": { 1275 | "es-define-property": "^1.0.0" 1276 | }, 1277 | "funding": { 1278 | "url": "https://github.com/sponsors/ljharb" 1279 | } 1280 | }, 1281 | "node_modules/has-symbols": { 1282 | "version": "1.1.0", 1283 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", 1284 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", 1285 | "engines": { 1286 | "node": ">= 0.4" 1287 | }, 1288 | "funding": { 1289 | "url": "https://github.com/sponsors/ljharb" 1290 | } 1291 | }, 1292 | "node_modules/has-tostringtag": { 1293 | "version": "1.0.2", 1294 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", 1295 | "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", 1296 | "dependencies": { 1297 | "has-symbols": "^1.0.3" 1298 | }, 1299 | "engines": { 1300 | "node": ">= 0.4" 1301 | }, 1302 | "funding": { 1303 | "url": "https://github.com/sponsors/ljharb" 1304 | } 1305 | }, 1306 | "node_modules/hasown": { 1307 | "version": "2.0.2", 1308 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 1309 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 1310 | "dependencies": { 1311 | "function-bind": "^1.1.2" 1312 | }, 1313 | "engines": { 1314 | "node": ">= 0.4" 1315 | } 1316 | }, 1317 | "node_modules/headers-polyfill": { 1318 | "version": "3.3.0", 1319 | "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-3.3.0.tgz", 1320 | "integrity": "sha512-5e57etwBpNcDc0b6KCVWEh/Ro063OxPvzVimUdM0/tsYM/T7Hfy3kknIGj78SFTOhNd8AZY41U8mOHoO4LzmIQ==" 1321 | }, 1322 | "node_modules/hono": { 1323 | "version": "4.7.2", 1324 | "resolved": "https://registry.npmjs.org/hono/-/hono-4.7.2.tgz", 1325 | "integrity": "sha512-8V5XxoOF6SI12jkHkzX/6aLBMU5GEF5g387EjVSQipS0DlxWgWGSMeEayY3CRBjtTUQYwLHx9JYouWqKzy2Vng==", 1326 | "engines": { 1327 | "node": ">=16.9.0" 1328 | } 1329 | }, 1330 | "node_modules/https-proxy-agent": { 1331 | "version": "7.0.6", 1332 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", 1333 | "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", 1334 | "dependencies": { 1335 | "agent-base": "^7.1.2", 1336 | "debug": "4" 1337 | }, 1338 | "engines": { 1339 | "node": ">= 14" 1340 | } 1341 | }, 1342 | "node_modules/humanize-ms": { 1343 | "version": "1.2.1", 1344 | "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", 1345 | "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", 1346 | "dependencies": { 1347 | "ms": "^2.0.0" 1348 | } 1349 | }, 1350 | "node_modules/ignore": { 1351 | "version": "7.0.3", 1352 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz", 1353 | "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==", 1354 | "engines": { 1355 | "node": ">= 4" 1356 | } 1357 | }, 1358 | "node_modules/inflight": { 1359 | "version": "1.0.6", 1360 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1361 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 1362 | "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", 1363 | "dependencies": { 1364 | "once": "^1.3.0", 1365 | "wrappy": "1" 1366 | } 1367 | }, 1368 | "node_modules/inherits": { 1369 | "version": "2.0.4", 1370 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1371 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 1372 | }, 1373 | "node_modules/is-docker": { 1374 | "version": "2.2.1", 1375 | "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", 1376 | "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", 1377 | "bin": { 1378 | "is-docker": "cli.js" 1379 | }, 1380 | "engines": { 1381 | "node": ">=8" 1382 | }, 1383 | "funding": { 1384 | "url": "https://github.com/sponsors/sindresorhus" 1385 | } 1386 | }, 1387 | "node_modules/is-number": { 1388 | "version": "7.0.0", 1389 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1390 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1391 | "engines": { 1392 | "node": ">=0.12.0" 1393 | } 1394 | }, 1395 | "node_modules/is-obj": { 1396 | "version": "2.0.0", 1397 | "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", 1398 | "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", 1399 | "engines": { 1400 | "node": ">=8" 1401 | } 1402 | }, 1403 | "node_modules/is-stream": { 1404 | "version": "2.0.1", 1405 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", 1406 | "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", 1407 | "engines": { 1408 | "node": ">=8" 1409 | }, 1410 | "funding": { 1411 | "url": "https://github.com/sponsors/sindresorhus" 1412 | } 1413 | }, 1414 | "node_modules/is-wsl": { 1415 | "version": "2.2.0", 1416 | "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", 1417 | "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", 1418 | "dependencies": { 1419 | "is-docker": "^2.0.0" 1420 | }, 1421 | "engines": { 1422 | "node": ">=8" 1423 | } 1424 | }, 1425 | "node_modules/isarray": { 1426 | "version": "2.0.5", 1427 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", 1428 | "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" 1429 | }, 1430 | "node_modules/isexe": { 1431 | "version": "2.0.0", 1432 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1433 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" 1434 | }, 1435 | "node_modules/json-bigint": { 1436 | "version": "1.0.0", 1437 | "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", 1438 | "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", 1439 | "dependencies": { 1440 | "bignumber.js": "^9.0.0" 1441 | } 1442 | }, 1443 | "node_modules/json-schema": { 1444 | "version": "0.4.0", 1445 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", 1446 | "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" 1447 | }, 1448 | "node_modules/json-stable-stringify": { 1449 | "version": "1.2.1", 1450 | "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.2.1.tgz", 1451 | "integrity": "sha512-Lp6HbbBgosLmJbjx0pBLbgvx68FaFU1sdkmBuckmhhJ88kL13OA51CDtR2yJB50eCNMH9wRqtQNNiAqQH4YXnA==", 1452 | "dependencies": { 1453 | "call-bind": "^1.0.8", 1454 | "call-bound": "^1.0.3", 1455 | "isarray": "^2.0.5", 1456 | "jsonify": "^0.0.1", 1457 | "object-keys": "^1.1.1" 1458 | }, 1459 | "engines": { 1460 | "node": ">= 0.4" 1461 | }, 1462 | "funding": { 1463 | "url": "https://github.com/sponsors/ljharb" 1464 | } 1465 | }, 1466 | "node_modules/jsonfile": { 1467 | "version": "6.1.0", 1468 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", 1469 | "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", 1470 | "dependencies": { 1471 | "universalify": "^2.0.0" 1472 | }, 1473 | "optionalDependencies": { 1474 | "graceful-fs": "^4.1.6" 1475 | } 1476 | }, 1477 | "node_modules/jsonify": { 1478 | "version": "0.0.1", 1479 | "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", 1480 | "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", 1481 | "funding": { 1482 | "url": "https://github.com/sponsors/ljharb" 1483 | } 1484 | }, 1485 | "node_modules/jwa": { 1486 | "version": "2.0.0", 1487 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", 1488 | "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", 1489 | "dependencies": { 1490 | "buffer-equal-constant-time": "1.0.1", 1491 | "ecdsa-sig-formatter": "1.0.11", 1492 | "safe-buffer": "^5.0.1" 1493 | } 1494 | }, 1495 | "node_modules/jws": { 1496 | "version": "4.0.0", 1497 | "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", 1498 | "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", 1499 | "dependencies": { 1500 | "jwa": "^2.0.0", 1501 | "safe-buffer": "^5.0.1" 1502 | } 1503 | }, 1504 | "node_modules/klaw-sync": { 1505 | "version": "6.0.0", 1506 | "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", 1507 | "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", 1508 | "dependencies": { 1509 | "graceful-fs": "^4.1.11" 1510 | } 1511 | }, 1512 | "node_modules/lodash.isequal": { 1513 | "version": "4.5.0", 1514 | "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", 1515 | "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", 1516 | "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead." 1517 | }, 1518 | "node_modules/math-intrinsics": { 1519 | "version": "1.1.0", 1520 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", 1521 | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", 1522 | "engines": { 1523 | "node": ">= 0.4" 1524 | } 1525 | }, 1526 | "node_modules/micromatch": { 1527 | "version": "4.0.8", 1528 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", 1529 | "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", 1530 | "dependencies": { 1531 | "braces": "^3.0.3", 1532 | "picomatch": "^2.3.1" 1533 | }, 1534 | "engines": { 1535 | "node": ">=8.6" 1536 | } 1537 | }, 1538 | "node_modules/mime-db": { 1539 | "version": "1.52.0", 1540 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1541 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 1542 | "engines": { 1543 | "node": ">= 0.6" 1544 | } 1545 | }, 1546 | "node_modules/mime-types": { 1547 | "version": "2.1.35", 1548 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1549 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1550 | "dependencies": { 1551 | "mime-db": "1.52.0" 1552 | }, 1553 | "engines": { 1554 | "node": ">= 0.6" 1555 | } 1556 | }, 1557 | "node_modules/minimatch": { 1558 | "version": "3.1.2", 1559 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1560 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1561 | "dependencies": { 1562 | "brace-expansion": "^1.1.7" 1563 | }, 1564 | "engines": { 1565 | "node": "*" 1566 | } 1567 | }, 1568 | "node_modules/minimist": { 1569 | "version": "1.2.8", 1570 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 1571 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 1572 | "funding": { 1573 | "url": "https://github.com/sponsors/ljharb" 1574 | } 1575 | }, 1576 | "node_modules/ms": { 1577 | "version": "2.1.3", 1578 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1579 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 1580 | }, 1581 | "node_modules/nanoid": { 1582 | "version": "3.3.11", 1583 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", 1584 | "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", 1585 | "funding": [ 1586 | { 1587 | "type": "github", 1588 | "url": "https://github.com/sponsors/ai" 1589 | } 1590 | ], 1591 | "bin": { 1592 | "nanoid": "bin/nanoid.cjs" 1593 | }, 1594 | "engines": { 1595 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1596 | } 1597 | }, 1598 | "node_modules/node-domexception": { 1599 | "version": "1.0.0", 1600 | "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", 1601 | "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", 1602 | "funding": [ 1603 | { 1604 | "type": "github", 1605 | "url": "https://github.com/sponsors/jimmywarting" 1606 | }, 1607 | { 1608 | "type": "github", 1609 | "url": "https://paypal.me/jimmywarting" 1610 | } 1611 | ], 1612 | "engines": { 1613 | "node": ">=10.5.0" 1614 | } 1615 | }, 1616 | "node_modules/node-fetch": { 1617 | "version": "2.7.0", 1618 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", 1619 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", 1620 | "dependencies": { 1621 | "whatwg-url": "^5.0.0" 1622 | }, 1623 | "engines": { 1624 | "node": "4.x || >=6.0.0" 1625 | }, 1626 | "peerDependencies": { 1627 | "encoding": "^0.1.0" 1628 | }, 1629 | "peerDependenciesMeta": { 1630 | "encoding": { 1631 | "optional": true 1632 | } 1633 | } 1634 | }, 1635 | "node_modules/oauth-1.0a": { 1636 | "version": "2.2.6", 1637 | "resolved": "https://registry.npmjs.org/oauth-1.0a/-/oauth-1.0a-2.2.6.tgz", 1638 | "integrity": "sha512-6bkxv3N4Gu5lty4viIcIAnq5GbxECviMBeKR3WX/q87SPQ8E8aursPZUtsXDnxCs787af09WPRBLqYrf/lwoYQ==" 1639 | }, 1640 | "node_modules/object-inspect": { 1641 | "version": "1.13.4", 1642 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", 1643 | "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", 1644 | "engines": { 1645 | "node": ">= 0.4" 1646 | }, 1647 | "funding": { 1648 | "url": "https://github.com/sponsors/ljharb" 1649 | } 1650 | }, 1651 | "node_modules/object-keys": { 1652 | "version": "1.1.1", 1653 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 1654 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 1655 | "engines": { 1656 | "node": ">= 0.4" 1657 | } 1658 | }, 1659 | "node_modules/once": { 1660 | "version": "1.4.0", 1661 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1662 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1663 | "dependencies": { 1664 | "wrappy": "1" 1665 | } 1666 | }, 1667 | "node_modules/open": { 1668 | "version": "7.4.2", 1669 | "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", 1670 | "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", 1671 | "dependencies": { 1672 | "is-docker": "^2.0.0", 1673 | "is-wsl": "^2.1.1" 1674 | }, 1675 | "engines": { 1676 | "node": ">=8" 1677 | }, 1678 | "funding": { 1679 | "url": "https://github.com/sponsors/sindresorhus" 1680 | } 1681 | }, 1682 | "node_modules/openai": { 1683 | "version": "4.95.0", 1684 | "resolved": "https://registry.npmjs.org/openai/-/openai-4.95.0.tgz", 1685 | "integrity": "sha512-tWHLTA+/HHyWlP8qg0mQLDSpI2NQLhk6zHLJL8yb59qn2pEI8rbEiAGSDPViLvi3BRDoQZIX5scaJ3xYGr2nhw==", 1686 | "dependencies": { 1687 | "@types/node": "^18.11.18", 1688 | "@types/node-fetch": "^2.6.4", 1689 | "abort-controller": "^3.0.0", 1690 | "agentkeepalive": "^4.2.1", 1691 | "form-data-encoder": "1.7.2", 1692 | "formdata-node": "^4.3.2", 1693 | "node-fetch": "^2.6.7" 1694 | }, 1695 | "bin": { 1696 | "openai": "bin/cli" 1697 | }, 1698 | "peerDependencies": { 1699 | "ws": "^8.18.0", 1700 | "zod": "^3.23.8" 1701 | }, 1702 | "peerDependenciesMeta": { 1703 | "ws": { 1704 | "optional": true 1705 | }, 1706 | "zod": { 1707 | "optional": true 1708 | } 1709 | } 1710 | }, 1711 | "node_modules/os-tmpdir": { 1712 | "version": "1.0.2", 1713 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 1714 | "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", 1715 | "engines": { 1716 | "node": ">=0.10.0" 1717 | } 1718 | }, 1719 | "node_modules/otpauth": { 1720 | "version": "9.3.6", 1721 | "resolved": "https://registry.npmjs.org/otpauth/-/otpauth-9.3.6.tgz", 1722 | "integrity": "sha512-eIcCvuEvcAAPHxUKC9Q4uCe0Fh/yRc5jv9z+f/kvyIF2LPrhgAOuLB7J9CssGYhND/BL8M9hlHBTFmffpoQlMQ==", 1723 | "dependencies": { 1724 | "@noble/hashes": "1.6.1" 1725 | }, 1726 | "funding": { 1727 | "url": "https://github.com/hectorm/otpauth?sponsor=1" 1728 | } 1729 | }, 1730 | "node_modules/ow": { 1731 | "version": "0.28.2", 1732 | "resolved": "https://registry.npmjs.org/ow/-/ow-0.28.2.tgz", 1733 | "integrity": "sha512-dD4UpyBh/9m4X2NVjA+73/ZPBRF+uF4zIMFvvQsabMiEK8x41L3rQ8EENOi35kyyoaJwNxEeJcP6Fj1H4U409Q==", 1734 | "dependencies": { 1735 | "@sindresorhus/is": "^4.2.0", 1736 | "callsites": "^3.1.0", 1737 | "dot-prop": "^6.0.1", 1738 | "lodash.isequal": "^4.5.0", 1739 | "vali-date": "^1.0.0" 1740 | }, 1741 | "engines": { 1742 | "node": ">=12" 1743 | }, 1744 | "funding": { 1745 | "url": "https://github.com/sponsors/sindresorhus" 1746 | } 1747 | }, 1748 | "node_modules/patch-package": { 1749 | "version": "8.0.0", 1750 | "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.0.0.tgz", 1751 | "integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==", 1752 | "dependencies": { 1753 | "@yarnpkg/lockfile": "^1.1.0", 1754 | "chalk": "^4.1.2", 1755 | "ci-info": "^3.7.0", 1756 | "cross-spawn": "^7.0.3", 1757 | "find-yarn-workspace-root": "^2.0.0", 1758 | "fs-extra": "^9.0.0", 1759 | "json-stable-stringify": "^1.0.2", 1760 | "klaw-sync": "^6.0.0", 1761 | "minimist": "^1.2.6", 1762 | "open": "^7.4.2", 1763 | "rimraf": "^2.6.3", 1764 | "semver": "^7.5.3", 1765 | "slash": "^2.0.0", 1766 | "tmp": "^0.0.33", 1767 | "yaml": "^2.2.2" 1768 | }, 1769 | "bin": { 1770 | "patch-package": "index.js" 1771 | }, 1772 | "engines": { 1773 | "node": ">=14", 1774 | "npm": ">5" 1775 | } 1776 | }, 1777 | "node_modules/path-is-absolute": { 1778 | "version": "1.0.1", 1779 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1780 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1781 | "engines": { 1782 | "node": ">=0.10.0" 1783 | } 1784 | }, 1785 | "node_modules/path-key": { 1786 | "version": "3.1.1", 1787 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1788 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1789 | "engines": { 1790 | "node": ">=8" 1791 | } 1792 | }, 1793 | "node_modules/picomatch": { 1794 | "version": "2.3.1", 1795 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1796 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1797 | "engines": { 1798 | "node": ">=8.6" 1799 | }, 1800 | "funding": { 1801 | "url": "https://github.com/sponsors/jonschlinkert" 1802 | } 1803 | }, 1804 | "node_modules/portkey-ai": { 1805 | "version": "1.8.0", 1806 | "resolved": "https://registry.npmjs.org/portkey-ai/-/portkey-ai-1.8.0.tgz", 1807 | "integrity": "sha512-2o3srjHQzZYnVLyvWT2zk5D7gDmKsS6y5N2jBz5yyQsDpBbSbKPRL8oeeGLz1QOV/WNNJKZzMqgb2KP35pcL4w==", 1808 | "dependencies": { 1809 | "agentkeepalive": "^4.5.0", 1810 | "dotenv": "^16.3.1", 1811 | "openai": "4.90.0", 1812 | "ws": "^8.18.1" 1813 | } 1814 | }, 1815 | "node_modules/portkey-ai/node_modules/openai": { 1816 | "version": "4.90.0", 1817 | "resolved": "https://registry.npmjs.org/openai/-/openai-4.90.0.tgz", 1818 | "integrity": "sha512-YCuHMMycqtCg1B8G9ezkOF0j8UnBWD3Al/zYaelpuXwU1yhCEv+Y4n9G20MnyGy6cH4GsFwOMrgstQ+bgG1PtA==", 1819 | "dependencies": { 1820 | "@types/node": "^18.11.18", 1821 | "@types/node-fetch": "^2.6.4", 1822 | "abort-controller": "^3.0.0", 1823 | "agentkeepalive": "^4.2.1", 1824 | "form-data-encoder": "1.7.2", 1825 | "formdata-node": "^4.3.2", 1826 | "node-fetch": "^2.6.7" 1827 | }, 1828 | "bin": { 1829 | "openai": "bin/cli" 1830 | }, 1831 | "peerDependencies": { 1832 | "ws": "^8.18.0", 1833 | "zod": "^3.23.8" 1834 | }, 1835 | "peerDependenciesMeta": { 1836 | "ws": { 1837 | "optional": true 1838 | }, 1839 | "zod": { 1840 | "optional": true 1841 | } 1842 | } 1843 | }, 1844 | "node_modules/proxy-from-env": { 1845 | "version": "1.1.0", 1846 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 1847 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" 1848 | }, 1849 | "node_modules/qs": { 1850 | "version": "6.14.0", 1851 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", 1852 | "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", 1853 | "dependencies": { 1854 | "side-channel": "^1.1.0" 1855 | }, 1856 | "engines": { 1857 | "node": ">=0.6" 1858 | }, 1859 | "funding": { 1860 | "url": "https://github.com/sponsors/ljharb" 1861 | } 1862 | }, 1863 | "node_modules/retry": { 1864 | "version": "0.13.1", 1865 | "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", 1866 | "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", 1867 | "engines": { 1868 | "node": ">= 4" 1869 | } 1870 | }, 1871 | "node_modules/rimraf": { 1872 | "version": "2.7.1", 1873 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", 1874 | "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", 1875 | "deprecated": "Rimraf versions prior to v4 are no longer supported", 1876 | "dependencies": { 1877 | "glob": "^7.1.3" 1878 | }, 1879 | "bin": { 1880 | "rimraf": "bin.js" 1881 | } 1882 | }, 1883 | "node_modules/safe-buffer": { 1884 | "version": "5.2.1", 1885 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1886 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1887 | "funding": [ 1888 | { 1889 | "type": "github", 1890 | "url": "https://github.com/sponsors/feross" 1891 | }, 1892 | { 1893 | "type": "patreon", 1894 | "url": "https://www.patreon.com/feross" 1895 | }, 1896 | { 1897 | "type": "consulting", 1898 | "url": "https://feross.org/support" 1899 | } 1900 | ] 1901 | }, 1902 | "node_modules/secure-json-parse": { 1903 | "version": "2.7.0", 1904 | "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", 1905 | "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==" 1906 | }, 1907 | "node_modules/semver": { 1908 | "version": "7.7.1", 1909 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", 1910 | "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", 1911 | "bin": { 1912 | "semver": "bin/semver.js" 1913 | }, 1914 | "engines": { 1915 | "node": ">=10" 1916 | } 1917 | }, 1918 | "node_modules/set-cookie-parser": { 1919 | "version": "2.7.1", 1920 | "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", 1921 | "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==" 1922 | }, 1923 | "node_modules/set-function-length": { 1924 | "version": "1.2.2", 1925 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", 1926 | "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", 1927 | "dependencies": { 1928 | "define-data-property": "^1.1.4", 1929 | "es-errors": "^1.3.0", 1930 | "function-bind": "^1.1.2", 1931 | "get-intrinsic": "^1.2.4", 1932 | "gopd": "^1.0.1", 1933 | "has-property-descriptors": "^1.0.2" 1934 | }, 1935 | "engines": { 1936 | "node": ">= 0.4" 1937 | } 1938 | }, 1939 | "node_modules/shebang-command": { 1940 | "version": "2.0.0", 1941 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1942 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1943 | "dependencies": { 1944 | "shebang-regex": "^3.0.0" 1945 | }, 1946 | "engines": { 1947 | "node": ">=8" 1948 | } 1949 | }, 1950 | "node_modules/shebang-regex": { 1951 | "version": "3.0.0", 1952 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1953 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1954 | "engines": { 1955 | "node": ">=8" 1956 | } 1957 | }, 1958 | "node_modules/side-channel": { 1959 | "version": "1.1.0", 1960 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", 1961 | "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", 1962 | "dependencies": { 1963 | "es-errors": "^1.3.0", 1964 | "object-inspect": "^1.13.3", 1965 | "side-channel-list": "^1.0.0", 1966 | "side-channel-map": "^1.0.1", 1967 | "side-channel-weakmap": "^1.0.2" 1968 | }, 1969 | "engines": { 1970 | "node": ">= 0.4" 1971 | }, 1972 | "funding": { 1973 | "url": "https://github.com/sponsors/ljharb" 1974 | } 1975 | }, 1976 | "node_modules/side-channel-list": { 1977 | "version": "1.0.0", 1978 | "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", 1979 | "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", 1980 | "dependencies": { 1981 | "es-errors": "^1.3.0", 1982 | "object-inspect": "^1.13.3" 1983 | }, 1984 | "engines": { 1985 | "node": ">= 0.4" 1986 | }, 1987 | "funding": { 1988 | "url": "https://github.com/sponsors/ljharb" 1989 | } 1990 | }, 1991 | "node_modules/side-channel-map": { 1992 | "version": "1.0.1", 1993 | "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", 1994 | "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", 1995 | "dependencies": { 1996 | "call-bound": "^1.0.2", 1997 | "es-errors": "^1.3.0", 1998 | "get-intrinsic": "^1.2.5", 1999 | "object-inspect": "^1.13.3" 2000 | }, 2001 | "engines": { 2002 | "node": ">= 0.4" 2003 | }, 2004 | "funding": { 2005 | "url": "https://github.com/sponsors/ljharb" 2006 | } 2007 | }, 2008 | "node_modules/side-channel-weakmap": { 2009 | "version": "1.0.2", 2010 | "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", 2011 | "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", 2012 | "dependencies": { 2013 | "call-bound": "^1.0.2", 2014 | "es-errors": "^1.3.0", 2015 | "get-intrinsic": "^1.2.5", 2016 | "object-inspect": "^1.13.3", 2017 | "side-channel-map": "^1.0.1" 2018 | }, 2019 | "engines": { 2020 | "node": ">= 0.4" 2021 | }, 2022 | "funding": { 2023 | "url": "https://github.com/sponsors/ljharb" 2024 | } 2025 | }, 2026 | "node_modules/slash": { 2027 | "version": "2.0.0", 2028 | "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", 2029 | "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", 2030 | "engines": { 2031 | "node": ">=6" 2032 | } 2033 | }, 2034 | "node_modules/supports-color": { 2035 | "version": "7.2.0", 2036 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 2037 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 2038 | "dependencies": { 2039 | "has-flag": "^4.0.0" 2040 | }, 2041 | "engines": { 2042 | "node": ">=8" 2043 | } 2044 | }, 2045 | "node_modules/tldts": { 2046 | "version": "6.1.78", 2047 | "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.78.tgz", 2048 | "integrity": "sha512-fSgYrW0ITH0SR/CqKMXIruYIPpNu5aDgUp22UhYoSrnUQwc7SBqifEBFNce7AAcygUPBo6a/gbtcguWdmko4RQ==", 2049 | "dependencies": { 2050 | "tldts-core": "^6.1.78" 2051 | }, 2052 | "bin": { 2053 | "tldts": "bin/cli.js" 2054 | } 2055 | }, 2056 | "node_modules/tldts-core": { 2057 | "version": "6.1.78", 2058 | "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.78.tgz", 2059 | "integrity": "sha512-jS0svNsB99jR6AJBmfmEWuKIgz91Haya91Z43PATaeHJ24BkMoNRb/jlaD37VYjb0mYf6gRL/HOnvS1zEnYBiw==" 2060 | }, 2061 | "node_modules/tmp": { 2062 | "version": "0.0.33", 2063 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 2064 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 2065 | "dependencies": { 2066 | "os-tmpdir": "~1.0.2" 2067 | }, 2068 | "engines": { 2069 | "node": ">=0.6.0" 2070 | } 2071 | }, 2072 | "node_modules/to-regex-range": { 2073 | "version": "5.0.1", 2074 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 2075 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 2076 | "dependencies": { 2077 | "is-number": "^7.0.0" 2078 | }, 2079 | "engines": { 2080 | "node": ">=8.0" 2081 | } 2082 | }, 2083 | "node_modules/tough-cookie": { 2084 | "version": "5.1.1", 2085 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.1.tgz", 2086 | "integrity": "sha512-Ek7HndSVkp10hmHP9V4qZO1u+pn1RU5sI0Fw+jCU3lyvuMZcgqsNgc6CmJJZyByK4Vm/qotGRJlfgAX8q+4JiA==", 2087 | "dependencies": { 2088 | "tldts": "^6.1.32" 2089 | }, 2090 | "engines": { 2091 | "node": ">=16" 2092 | } 2093 | }, 2094 | "node_modules/tr46": { 2095 | "version": "0.0.3", 2096 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 2097 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" 2098 | }, 2099 | "node_modules/tslib": { 2100 | "version": "2.8.1", 2101 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", 2102 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" 2103 | }, 2104 | "node_modules/twitter-api-v2": { 2105 | "version": "1.20.1", 2106 | "resolved": "https://registry.npmjs.org/twitter-api-v2/-/twitter-api-v2-1.20.1.tgz", 2107 | "integrity": "sha512-sRsjtXAC3zdJEY9sA8Gf99MeReyws26092XpXNL0Rtb74mtGykYptLHI/7blC1txt4c4HkN6hMIKiUx8JNR+AQ==" 2108 | }, 2109 | "node_modules/type-fest": { 2110 | "version": "4.35.0", 2111 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.35.0.tgz", 2112 | "integrity": "sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==", 2113 | "engines": { 2114 | "node": ">=16" 2115 | }, 2116 | "funding": { 2117 | "url": "https://github.com/sponsors/sindresorhus" 2118 | } 2119 | }, 2120 | "node_modules/typescript": { 2121 | "version": "5.8.3", 2122 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", 2123 | "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", 2124 | "bin": { 2125 | "tsc": "bin/tsc", 2126 | "tsserver": "bin/tsserver" 2127 | }, 2128 | "engines": { 2129 | "node": ">=14.17" 2130 | } 2131 | }, 2132 | "node_modules/undici": { 2133 | "version": "7.3.0", 2134 | "resolved": "https://registry.npmjs.org/undici/-/undici-7.3.0.tgz", 2135 | "integrity": "sha512-Qy96NND4Dou5jKoSJ2gm8ax8AJM/Ey9o9mz7KN1bb9GP+G0l20Zw8afxTnY2f4b7hmhn/z8aC2kfArVQlAhFBw==", 2136 | "engines": { 2137 | "node": ">=20.18.1" 2138 | } 2139 | }, 2140 | "node_modules/undici-types": { 2141 | "version": "5.26.5", 2142 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 2143 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" 2144 | }, 2145 | "node_modules/universalify": { 2146 | "version": "2.0.1", 2147 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", 2148 | "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", 2149 | "engines": { 2150 | "node": ">= 10.0.0" 2151 | } 2152 | }, 2153 | "node_modules/url-template": { 2154 | "version": "2.0.8", 2155 | "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", 2156 | "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==" 2157 | }, 2158 | "node_modules/uuid": { 2159 | "version": "9.0.1", 2160 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", 2161 | "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", 2162 | "funding": [ 2163 | "https://github.com/sponsors/broofa", 2164 | "https://github.com/sponsors/ctavan" 2165 | ], 2166 | "bin": { 2167 | "uuid": "dist/bin/uuid" 2168 | } 2169 | }, 2170 | "node_modules/vali-date": { 2171 | "version": "1.0.0", 2172 | "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", 2173 | "integrity": "sha512-sgECfZthyaCKW10N0fm27cg8HYTFK5qMWgypqkXMQ4Wbl/zZKx7xZICgcoxIIE+WFAP/MBL2EFwC/YvLxw3Zeg==", 2174 | "engines": { 2175 | "node": ">=0.10.0" 2176 | } 2177 | }, 2178 | "node_modules/webidl-conversions": { 2179 | "version": "7.0.0", 2180 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", 2181 | "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", 2182 | "optional": true, 2183 | "engines": { 2184 | "node": ">=12" 2185 | } 2186 | }, 2187 | "node_modules/whatwg-url": { 2188 | "version": "5.0.0", 2189 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 2190 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 2191 | "dependencies": { 2192 | "tr46": "~0.0.3", 2193 | "webidl-conversions": "^3.0.0" 2194 | } 2195 | }, 2196 | "node_modules/whatwg-url/node_modules/webidl-conversions": { 2197 | "version": "3.0.1", 2198 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 2199 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" 2200 | }, 2201 | "node_modules/which": { 2202 | "version": "2.0.2", 2203 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2204 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2205 | "dependencies": { 2206 | "isexe": "^2.0.0" 2207 | }, 2208 | "bin": { 2209 | "node-which": "bin/node-which" 2210 | }, 2211 | "engines": { 2212 | "node": ">= 8" 2213 | } 2214 | }, 2215 | "node_modules/wrappy": { 2216 | "version": "1.0.2", 2217 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2218 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" 2219 | }, 2220 | "node_modules/ws": { 2221 | "version": "8.18.1", 2222 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", 2223 | "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", 2224 | "engines": { 2225 | "node": ">=10.0.0" 2226 | }, 2227 | "peerDependencies": { 2228 | "bufferutil": "^4.0.1", 2229 | "utf-8-validate": ">=5.0.2" 2230 | }, 2231 | "peerDependenciesMeta": { 2232 | "bufferutil": { 2233 | "optional": true 2234 | }, 2235 | "utf-8-validate": { 2236 | "optional": true 2237 | } 2238 | } 2239 | }, 2240 | "node_modules/yaml": { 2241 | "version": "2.7.1", 2242 | "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz", 2243 | "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", 2244 | "bin": { 2245 | "yaml": "bin.mjs" 2246 | }, 2247 | "engines": { 2248 | "node": ">= 14" 2249 | } 2250 | }, 2251 | "node_modules/zod": { 2252 | "version": "3.24.2", 2253 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", 2254 | "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", 2255 | "funding": { 2256 | "url": "https://github.com/sponsors/colinhacks" 2257 | } 2258 | } 2259 | } 2260 | } 2261 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tai_scripts", 3 | "version": "0.1.0", 4 | "description": "Taelin AI Scripts", 5 | "main": "index.js", 6 | "bin": { 7 | "csh": "ChatSH.ts", 8 | "holefill": "HoleFill.ts" 9 | }, 10 | "scripts": { 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/victortaelin/ai-scripts.git" 16 | }, 17 | "keywords": [ 18 | "ai" 19 | ], 20 | "author": "VictorTaelin", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/victortaelin/ai-scripts/issues" 24 | }, 25 | "dependencies": { 26 | "@anthropic-ai/sdk": "^0.39.0", 27 | "@google/generative-ai": "^0.24.0", 28 | "@openrouter/ai-sdk-provider": "^0.4.5", 29 | "@portkey-ai/gateway": "^1.9.15", 30 | "agent-twitter-client-taelin-fork": "^0.0.26", 31 | "apify-client": "^2.12.2", 32 | "commander": "^13.1.0", 33 | "gateway": "^1.0.0", 34 | "googleapis": "^148.0.0", 35 | "gpt-tokenizer": "^2.9.0", 36 | "groq-sdk": "^0.19.0", 37 | "ignore": "^7.0.3", 38 | "minimist": "^1.2.8", 39 | "oauth-1.0a": "^2.2.6", 40 | "openai": "^4.95.0", 41 | "portkey-ai": "^1.8.0", 42 | "typescript": "^5.8.3" 43 | }, 44 | "homepage": "https://github.com/victortaelin/ai-scripts#readme", 45 | "devDependencies": { 46 | "@types/minimist": "^1.2.5" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "NodeNext", 5 | "moduleResolution": "NodeNext", 6 | "esModuleInterop": true, 7 | "allowSyntheticDefaultImports": true, 8 | "strict": true, 9 | "outDir": "./dist", 10 | "rootDir": "./", 11 | "baseUrl": "." 12 | }, 13 | "include": ["*.ts", "Vendors/*.ts"], 14 | "exclude": ["node_modules"] 15 | } 16 | --------------------------------------------------------------------------------