autoagent-cli
Version:
Run autonomous AI agents using Claude or Gemini for task execution
285 lines (284 loc) • 13.1 kB
JavaScript
;
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.,!?;:]/;