UNPKG

autoagent-cli

Version:

Run autonomous AI agents using Claude or Gemini for task execution

285 lines (284 loc) 13.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StreamFormatter = void 0; const colors = { RED: '\x1b[0;31m', GREEN: '\x1b[0;32m', YELLOW: '\x1b[1;33m', BLUE: '\x1b[0;34m', PURPLE: '\x1b[0;35m', CYAN: '\x1b[0;36m', WHITE: '\x1b[1;37m', GRAY: '\x1b[0;90m', NC: '\x1b[0m' }; class StreamFormatter { static formatHeader(provider) { const header = provider === 'claude' ? '🤖 CLAUDE AGENT' : '🤖 GEMINI AGENT'; console.log(`${colors.CYAN}┌─────────────────────────────────────────────────────────────┐${colors.NC}`); console.log(`${colors.CYAN}${header}${colors.NC}`); console.log(`${colors.CYAN}└─────────────────────────────────────────────────────────────┘${colors.NC}`); console.log(''); } static formatClaudeMessage(message) { try { const type = message.type; switch (type) { case 'system': { if (message.subtype === 'init') { console.log(`${colors.GRAY}🔧 System initialized${colors.NC}`); if (typeof message.model === 'string') { console.log(` Model: ${message.model}`); } const tools = message.tools; if (Array.isArray(tools) && tools.length > 0) { console.log(` Tools available: ${tools.length}`); } console.log(''); } break; } case 'assistant': { const msg = message.message; if (msg !== null && typeof msg === 'object' && Array.isArray(msg.content)) { for (const content of msg.content) { if (typeof content === 'object' && content !== null) { const contentObj = content; if (contentObj.type === 'tool_use' && typeof contentObj.name === 'string') { console.log(`${colors.BLUE}🔧 Using tool: ${colors.WHITE}${contentObj.name}${colors.NC}`); } else if (contentObj.type === 'text' && typeof contentObj.text === 'string') { console.log(`${colors.WHITE}💭 Agent: ${colors.NC}${contentObj.text}`); console.log(''); } } } } break; } case 'user': { const msg = message.message; if (msg !== null && typeof msg === 'object' && Array.isArray(msg.content)) { for (const content of msg.content) { if (typeof content === 'object' && content !== null) { const contentObj = content; if (contentObj.type === 'tool_result' && typeof contentObj.content === 'string') { const result = contentObj.content; if (result.length > 300) { console.log(`${colors.GREEN}✅ Tool result: ${colors.GRAY}${result.substring(0, 300)}...${colors.NC}`); } else { console.log(`${colors.GREEN}✅ Tool result: ${colors.GRAY}${result}${colors.NC}`); } console.log(''); } } } } break; } case 'result': { if (message.is_error === false) { console.log(`${colors.GREEN}✅ Task completed successfully!${colors.NC}`); } else if (message.is_error === true) { console.log(`${colors.RED}❌ Task failed${colors.NC}`); } console.log(''); break; } default: { if (type !== '' && type !== 'empty') { console.log(`${colors.GRAY}📄 ${type}${colors.NC}`); } break; } } } catch (error) { } } static formatGeminiMessage(message) { try { const type = message.type; switch (type) { case 'tool_code': { const toolCode = message.content || ''; console.log(`${colors.BLUE}🔧 Using tool:${colors.NC}\n${colors.WHITE}${toolCode}${colors.NC}`); console.log(''); break; } case 'model_output': { const textContent = message.content || ''; console.log(`${colors.WHITE}💭 Agent: ${colors.NC}${textContent}`); console.log(''); break; } case 'tool_result': { const content = message.content || ''; if (content.length > 300) { console.log(`${colors.GREEN}✅ Tool result: ${colors.GRAY}${content.substring(0, 300)}...${colors.NC}`); } else { console.log(`${colors.GREEN}✅ Tool result: ${colors.GRAY}${content}${colors.NC}`); } console.log(''); break; } case 'result': { const status = message.status || 'error'; if (status === 'success') { console.log(`${colors.GREEN}✅ Task completed successfully!${colors.NC}`); } else { console.log(`${colors.RED}❌ Task failed${colors.NC}`); } console.log(''); break; } default: { if (type !== '' && type !== 'empty') { console.log(`${colors.GRAY}📄 ${type}${colors.NC}`); } break; } } } catch (error) { } } static showHeader(provider) { this.formatHeader(provider); } static showFooter() { console.log(`${colors.CYAN}└─────────────────────────────────────────────────────────────┘${colors.NC}`); } static isAbbreviation(textBefore, textAfter) { const words = textBefore.trim().split(/\s+/); const lastWord = words[words.length - 1]; if (lastWord === undefined || lastWord === null || lastWord.length === 0) { return false; } const wordWithoutPeriod = lastWord.replace(/\.$/, ''); const isInAbbreviationList = this.ABBREVIATIONS.has(wordWithoutPeriod); if (!isInAbbreviationList) { return false; } const afterTrimmed = textAfter.trim(); if (afterTrimmed.length > 0 && /^[A-Z]/.test(afterTrimmed)) { if (['Dr', 'Mr', 'Mrs', 'Ms', 'Prof', 'Rev', 'Hon', 'Capt', 'Lt', 'Sgt'].includes(wordWithoutPeriod)) { const afterWords = afterTrimmed.split(/\s+/); const firstWord = afterWords[0]; if (afterWords.length > 0 && firstWord !== undefined && /^[A-Z][a-z]/.test(firstWord)) { return true; } } return false; } return true; } static isSpecialPattern(fullText, periodIndex) { const beforePeriod = fullText.substring(Math.max(0, periodIndex - 10), periodIndex); const afterPeriod = fullText.substring(periodIndex + 1, periodIndex + 10); if (/\d$/.test(beforePeriod) && /^\d/.test(afterPeriod)) { return true; } const contextStart = Math.max(0, periodIndex - 50); const contextEnd = Math.min(fullText.length, periodIndex + 50); const context = fullText.substring(contextStart, contextEnd); const relativeIndex = periodIndex - contextStart; for (const pattern of [this.URL_PATTERN, this.EMAIL_PATTERN, this.FILE_PATH_PATTERN]) { const matches = [...context.matchAll(new RegExp(pattern, 'g'))]; for (const match of matches) { if (match.index !== undefined && match.index <= relativeIndex && match.index + match[0].length > relativeIndex) { return true; } } } return false; } static formatGeminiOutput(chunk) { try { if (process.env.AUTOAGENT_DISABLE_GEMINI_FORMATTING === 'true') { return chunk; } this.buffer += chunk; const bufferSize = parseInt(process.env.AUTOAGENT_GEMINI_BUFFER_SIZE ?? '1000', 10); const matches = [...this.buffer.matchAll(this.SENTENCE_PATTERN)]; if (matches.length === 0) { if (this.buffer.length > bufferSize) { const output = this.buffer; this.buffer = ''; return output; } return ''; } let lastIndex = 0; let output = ''; for (let i = 0; i < matches.length; i++) { const match = matches[i]; if (!match || match.index === undefined) { continue; } const endIndex = match.index + match[0].length; const isLastMatch = i === matches.length - 1; const hasMoreText = endIndex < this.buffer.length; if (isLastMatch && hasMoreText) { break; } const sentenceCandidate = this.buffer.substring(lastIndex, endIndex); const textBeforePeriod = this.buffer.substring(lastIndex, match.index); const textAfterPeriod = this.buffer.substring(endIndex); if (match[0].startsWith('.') && this.isAbbreviation(textBeforePeriod, textAfterPeriod)) { continue; } if (match[0].startsWith('.') && this.isSpecialPattern(this.buffer, match.index)) { continue; } const sentence = sentenceCandidate.trim(); if (sentence) { output += sentence + '\n\n'; } lastIndex = endIndex; } this.buffer = this.buffer.substring(lastIndex); if (process.env.AUTOAGENT_DEBUG_FORMATTING === 'true') { console.error('[DEBUG] Buffer size:', this.buffer.length); console.error('[DEBUG] Output size:', output.length); } return output; } catch (error) { const output = this.buffer; this.buffer = ''; return output; } } static flushGeminiBuffer() { const output = this.buffer.trim(); this.buffer = ''; return output ? output + '\n' : ''; } static displayGeminiText(text) { if (text.trim()) { console.log(text.trim()); } } } exports.StreamFormatter = StreamFormatter; StreamFormatter.buffer = ''; StreamFormatter.SENTENCE_PATTERN = /[.!?]+["']?(?:\s+|$)/g; StreamFormatter.ABBREVIATIONS = new Set([ 'Dr', 'Mr', 'Mrs', 'Ms', 'Prof', 'Rev', 'Hon', 'Capt', 'Lt', 'Sgt', 'Inc', 'Corp', 'Ltd', 'LLC', 'Co', 'Assoc', 'Dept', 'Mgmt', 'Ph.D', 'M.A', 'B.A', 'B.S', 'M.S', 'etc', 'vs', 'i.e', 'e.g', 'St', 'Ave', 'Blvd', 'Rd', 'U.S.A', 'U.K', 'N.Y', 'L.A', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun', 'a.m', 'p.m', 'API', 'URL', 'HTTP', 'HTTPS', 'TCP', 'UDP', 'SQL', 'JSON', 'XML', 'HTML', 'CSS', 'JS' ]); StreamFormatter.URL_PATTERN = /https?:\/\/[^\s]*[^\s.,!?;:]/; StreamFormatter.EMAIL_PATTERN = /\S+@\S+\.\S*[^\s.,!?;:]/; StreamFormatter.FILE_PATH_PATTERN = /(?:\.\/|\/|[A-Za-z]:\\)[^\s]*[^\s.,!?;:]/;