-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest-cli.js
More file actions
210 lines (185 loc) · 7.17 KB
/
Copy pathtest-cli.js
File metadata and controls
210 lines (185 loc) · 7.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
// ==========================================
// CLI Test Mode — test your AI without WhatsApp
// ==========================================
// Run: npm test
// Type messages in the terminal, AI responds.
// Simulates both human and AI-to-AI messages.
import readline from 'readline';
import config from './config.js';
import { chat } from './providers/index.js';
import { parseIncoming, createAgentMessage, createReply } from './protocol.js';
import { createGroup, broadcastToGroup, getGroupContext, listGroups, addMember } from './groups.js';
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const history = [
{
role: 'system',
content: `You are ${config.agent.name}, a personal AI assistant. Agent ID: ${config.agent.id}. You are in CLI test mode.`,
},
];
// Fake WhatsApp client for testing groups
const fakeClient = {
async sendMessage(phone, text) {
const parsed = parseIncoming(text);
if (parsed.type === 'agent') {
console.log(`\n [→ Sent to ${phone}] (protocol: ${parsed.message.intent})`);
console.log(` Payload: ${JSON.stringify(parsed.message.payload).slice(0, 200)}`);
} else {
console.log(`\n [→ Sent to ${phone}]: ${text.slice(0, 300)}`);
}
},
};
function printHelp() {
console.log(`
╔══════════════════════════════════════════════╗
║ CLI Test Mode — Commands ║
╠══════════════════════════════════════════════╣
║ (just type) → Chat with your AI ║
║ /agent → Simulate an AI-to-AI message ║
║ /group → Create a test group ║
║ /broadcast → Send to group ║
║ /groups → List all groups ║
║ /provider → Show current AI provider ║
║ /providers → List all available providers ║
║ /help → Show this menu ║
║ /quit → Exit ║
╚══════════════════════════════════════════════╝
`);
}
const ALL_PROVIDERS = [
'openai', 'anthropic', 'google', 'mistral', 'cohere', 'groq',
'ollama', 'deepseek', 'xai', 'perplexity', 'together', 'fireworks',
'codex', 'copilot', 'claude-code', 'claude-cowork',
];
async function handleInput(input) {
const trimmed = input.trim();
if (!trimmed) return;
// --- Commands ---
if (trimmed === '/quit' || trimmed === '/exit') {
console.log('\nBye!');
process.exit(0);
}
if (trimmed === '/help') {
printHelp();
return;
}
if (trimmed === '/provider') {
console.log(`\n Active provider: ${config.aiProvider} (model: ${config.providers[config.aiProvider]?.model || config.providers.claudeCode?.model || 'default'})\n`);
return;
}
if (trimmed === '/providers') {
console.log('\n Available providers:');
for (const p of ALL_PROVIDERS) {
const active = p === config.aiProvider ? ' ← ACTIVE' : '';
console.log(` - ${p}${active}`);
}
console.log();
return;
}
if (trimmed === '/agent') {
// Simulate receiving an AI-to-AI protocol message
const testMsg = createAgentMessage({
from: { agentId: 'test_agent', agentName: 'TestBot', phone: '+0000000000' },
to: { agentId: config.agent.id, agentName: config.agent.name },
intent: 'chat',
payload: 'Hello! I am another AI agent. What can you help me with?',
});
console.log('\n [Simulating incoming agent message...]');
console.log(` From: ${testMsg.from.agentName} | Intent: ${testMsg.intent}`);
const incoming = parseIncoming(JSON.stringify(testMsg));
history.push({
role: 'user',
content: `[AI Agent "${incoming.message.from.agentName}" sent a ${incoming.message.intent} message]: ${JSON.stringify(incoming.message.payload)}`,
});
console.log('\n Thinking...');
const response = await chat(history);
history.push({ role: 'assistant', content: response });
console.log(`\n ${config.agent.name}: ${response}\n`);
// Show what the reply protocol message looks like
const reply = createReply(incoming.message, {
agentId: config.agent.id,
agentName: config.agent.name,
}, response);
console.log(' [Protocol reply that would be sent back]:');
console.log(` ${JSON.stringify(reply, null, 2).split('\n').join('\n ')}\n`);
return;
}
if (trimmed === '/group') {
const group = createGroup({
name: 'Test Group',
purpose: 'Testing AI-to-AI group communication',
members: [
{ phone: '+1111111111', agentId: 'bot_alice', agentName: 'AliceAI' },
{ phone: '+2222222222', agentId: 'bot_bob', agentName: 'BobAI' },
],
});
console.log(`\n Created group: "${group.name}" (${group.groupId})`);
console.log(` Members: ${group.members.map(m => m.agentName).join(', ')}\n`);
return;
}
if (trimmed === '/groups') {
const all = listGroups();
if (all.length === 0) {
console.log('\n No groups yet. Use /group to create one.\n');
} else {
console.log('\n Groups:');
for (const g of all) {
console.log(` - "${g.name}" (${g.groupId}) — ${g.members.length} members`);
}
console.log();
}
return;
}
if (trimmed === '/broadcast') {
const all = listGroups();
if (all.length === 0) {
console.log('\n No groups. Use /group first.\n');
return;
}
const group = all[0];
const self = { agentId: config.agent.id, agentName: config.agent.name };
console.log(`\n Broadcasting to "${group.name}"...`);
await broadcastToGroup(group.groupId, self, 'group-chat', 'Hello group! This is a test broadcast.', fakeClient);
console.log(' Done!\n');
return;
}
// --- Normal chat ---
history.push({ role: 'user', content: trimmed });
console.log('\n Thinking...');
try {
const response = await chat(history);
history.push({ role: 'assistant', content: response });
console.log(`\n ${config.agent.name}: ${response}\n`);
} catch (err) {
console.error(`\n Error: ${err.message}\n`);
history.pop(); // remove the failed user message
}
}
async function main() {
console.log('===========================================');
console.log(` AI Agent CLI Test Mode`);
console.log(` Agent: ${config.agent.name} (${config.agent.id})`);
console.log(` Provider: ${config.aiProvider}`);
console.log('===========================================');
printHelp();
// Verify provider loads
try {
console.log(' Loading AI provider...');
const { getProvider } = await import('./providers/index.js');
await getProvider();
console.log(' Provider loaded successfully!\n');
} catch (err) {
console.error(` Failed to load provider "${config.aiProvider}": ${err.message}`);
console.error(' Check your .env file and API key.\n');
}
const prompt = () => {
rl.question('You: ', async (input) => {
await handleInput(input);
prompt();
});
};
prompt();
}
main().catch(console.error);