@agentforscience/flamebird 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +370 -0
- package/dist/actions/action-executor.d.ts +72 -0
- package/dist/actions/action-executor.d.ts.map +1 -0
- package/dist/actions/action-executor.js +458 -0
- package/dist/actions/action-executor.js.map +1 -0
- package/dist/agents/agent-manager.d.ts +90 -0
- package/dist/agents/agent-manager.d.ts.map +1 -0
- package/dist/agents/agent-manager.js +269 -0
- package/dist/agents/agent-manager.js.map +1 -0
- package/dist/api/agent4science-client.d.ts +297 -0
- package/dist/api/agent4science-client.d.ts.map +1 -0
- package/dist/api/agent4science-client.js +386 -0
- package/dist/api/agent4science-client.js.map +1 -0
- package/dist/cli/commands/add-agent.d.ts +13 -0
- package/dist/cli/commands/add-agent.d.ts.map +1 -0
- package/dist/cli/commands/add-agent.js +76 -0
- package/dist/cli/commands/add-agent.js.map +1 -0
- package/dist/cli/commands/community.d.ts +20 -0
- package/dist/cli/commands/community.d.ts.map +1 -0
- package/dist/cli/commands/community.js +1180 -0
- package/dist/cli/commands/community.js.map +1 -0
- package/dist/cli/commands/config.d.ts +12 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +152 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/create-agent.d.ts +12 -0
- package/dist/cli/commands/create-agent.d.ts.map +1 -0
- package/dist/cli/commands/create-agent.js +1780 -0
- package/dist/cli/commands/create-agent.js.map +1 -0
- package/dist/cli/commands/init.d.ts +15 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +487 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/interactive.d.ts +6 -0
- package/dist/cli/commands/interactive.d.ts.map +1 -0
- package/dist/cli/commands/interactive.js +447 -0
- package/dist/cli/commands/interactive.js.map +1 -0
- package/dist/cli/commands/list-agents.d.ts +10 -0
- package/dist/cli/commands/list-agents.d.ts.map +1 -0
- package/dist/cli/commands/list-agents.js +67 -0
- package/dist/cli/commands/list-agents.js.map +1 -0
- package/dist/cli/commands/play.d.ts +30 -0
- package/dist/cli/commands/play.d.ts.map +1 -0
- package/dist/cli/commands/play.js +1890 -0
- package/dist/cli/commands/play.js.map +1 -0
- package/dist/cli/commands/setup-production.d.ts +7 -0
- package/dist/cli/commands/setup-production.d.ts.map +1 -0
- package/dist/cli/commands/setup-production.js +127 -0
- package/dist/cli/commands/setup-production.js.map +1 -0
- package/dist/cli/commands/start.d.ts +15 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +89 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +6 -0
- package/dist/cli/commands/stats.d.ts.map +1 -0
- package/dist/cli/commands/stats.js +74 -0
- package/dist/cli/commands/stats.js.map +1 -0
- package/dist/cli/commands/status.d.ts +10 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +121 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/index.d.ts +13 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +174 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/ensure-credentials.d.ts +32 -0
- package/dist/cli/utils/ensure-credentials.d.ts.map +1 -0
- package/dist/cli/utils/ensure-credentials.js +280 -0
- package/dist/cli/utils/ensure-credentials.js.map +1 -0
- package/dist/cli/utils/local-agents.d.ts +49 -0
- package/dist/cli/utils/local-agents.d.ts.map +1 -0
- package/dist/cli/utils/local-agents.js +117 -0
- package/dist/cli/utils/local-agents.js.map +1 -0
- package/dist/config/config.d.ts +28 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +182 -0
- package/dist/config/config.js.map +1 -0
- package/dist/db/database.d.ts +150 -0
- package/dist/db/database.d.ts.map +1 -0
- package/dist/db/database.js +838 -0
- package/dist/db/database.js.map +1 -0
- package/dist/engagement/proactive-engine.d.ts +246 -0
- package/dist/engagement/proactive-engine.d.ts.map +1 -0
- package/dist/engagement/proactive-engine.js +1753 -0
- package/dist/engagement/proactive-engine.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +87 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/llm-client.d.ts +181 -0
- package/dist/llm/llm-client.d.ts.map +1 -0
- package/dist/llm/llm-client.js +658 -0
- package/dist/llm/llm-client.js.map +1 -0
- package/dist/logging/logger.d.ts +14 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +47 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/polling/notification-poller.d.ts +70 -0
- package/dist/polling/notification-poller.d.ts.map +1 -0
- package/dist/polling/notification-poller.js +190 -0
- package/dist/polling/notification-poller.js.map +1 -0
- package/dist/rate-limit/rate-limiter.d.ts +56 -0
- package/dist/rate-limit/rate-limiter.d.ts.map +1 -0
- package/dist/rate-limit/rate-limiter.js +202 -0
- package/dist/rate-limit/rate-limiter.js.map +1 -0
- package/dist/runtime/event-loop.d.ts +101 -0
- package/dist/runtime/event-loop.d.ts.map +1 -0
- package/dist/runtime/event-loop.js +680 -0
- package/dist/runtime/event-loop.js.map +1 -0
- package/dist/tools/manager-agent.d.ts +48 -0
- package/dist/tools/manager-agent.d.ts.map +1 -0
- package/dist/tools/manager-agent.js +440 -0
- package/dist/tools/manager-agent.js.map +1 -0
- package/dist/tools/paper-tools.d.ts +70 -0
- package/dist/tools/paper-tools.d.ts.map +1 -0
- package/dist/tools/paper-tools.js +446 -0
- package/dist/tools/paper-tools.js.map +1 -0
- package/dist/types.d.ts +266 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/cost-tracker.d.ts +51 -0
- package/dist/utils/cost-tracker.d.ts.map +1 -0
- package/dist/utils/cost-tracker.js +161 -0
- package/dist/utils/cost-tracker.js.map +1 -0
- package/dist/utils/similarity.d.ts +37 -0
- package/dist/utils/similarity.d.ts.map +1 -0
- package/dist/utils/similarity.js +78 -0
- package/dist/utils/similarity.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status Command
|
|
3
|
+
* Shows runtime status and agent activity
|
|
4
|
+
*/
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { loadConfig } from '../../config/config.js';
|
|
7
|
+
import { createDatabase, getDatabase } from '../../db/database.js';
|
|
8
|
+
import { createAgentManager, getAgentManager } from '../../agents/agent-manager.js';
|
|
9
|
+
import { getEventLoop } from '../../runtime/event-loop.js';
|
|
10
|
+
export async function statusCommand(options) {
|
|
11
|
+
const displayStatus = () => {
|
|
12
|
+
// Clear screen in watch mode
|
|
13
|
+
if (options.watch) {
|
|
14
|
+
console.clear();
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
const config = loadConfig();
|
|
18
|
+
let db = getDatabase();
|
|
19
|
+
if (!db) {
|
|
20
|
+
db = createDatabase(config.database.path);
|
|
21
|
+
}
|
|
22
|
+
let manager = getAgentManager();
|
|
23
|
+
if (!manager) {
|
|
24
|
+
manager = createAgentManager(config.security.encryptionKey);
|
|
25
|
+
}
|
|
26
|
+
// Header
|
|
27
|
+
console.log(chalk.bold('\n═══════════════════════════════════════'));
|
|
28
|
+
console.log(chalk.bold(' Agent4Science Agent Runtime Status'));
|
|
29
|
+
console.log(chalk.bold('═══════════════════════════════════════\n'));
|
|
30
|
+
// Runtime status
|
|
31
|
+
const eventLoop = getEventLoop();
|
|
32
|
+
if (eventLoop) {
|
|
33
|
+
const stats = eventLoop.getStats();
|
|
34
|
+
const uptime = Math.floor((Date.now() - stats.startTime.getTime()) / 1000);
|
|
35
|
+
const hours = Math.floor(uptime / 3600);
|
|
36
|
+
const minutes = Math.floor((uptime % 3600) / 60);
|
|
37
|
+
const seconds = uptime % 60;
|
|
38
|
+
console.log(chalk.bold('Runtime:'));
|
|
39
|
+
console.log(` Status: ${chalk.green('● Running')}`);
|
|
40
|
+
console.log(` Uptime: ${hours}h ${minutes}m ${seconds}s`);
|
|
41
|
+
console.log(` Ticks: ${stats.tickCount}`);
|
|
42
|
+
console.log(` Actions: ${stats.actionsExecuted}`);
|
|
43
|
+
console.log(` Errors: ${stats.errorsCount > 0 ? chalk.red(stats.errorsCount) : chalk.green(stats.errorsCount)}`);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
console.log(chalk.bold('Runtime:'));
|
|
47
|
+
console.log(` Status: ${chalk.gray('○ Stopped')}`);
|
|
48
|
+
}
|
|
49
|
+
// Agent status
|
|
50
|
+
console.log('\n' + chalk.bold('Agents:'));
|
|
51
|
+
const agentIds = manager.getAgentIds();
|
|
52
|
+
if (agentIds.length === 0) {
|
|
53
|
+
console.log(chalk.gray(' No agents configured'));
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
for (const agentId of agentIds) {
|
|
57
|
+
const runtime = manager.getRuntime(agentId);
|
|
58
|
+
if (!runtime)
|
|
59
|
+
continue;
|
|
60
|
+
const { config: agentConfig, state, lastPollTime, lastActionTime } = runtime;
|
|
61
|
+
const status = agentConfig.enabled ? chalk.green('●') : chalk.gray('○');
|
|
62
|
+
const stateEmoji = {
|
|
63
|
+
idle: '💤',
|
|
64
|
+
polling: '🔄',
|
|
65
|
+
thinking: '🤔',
|
|
66
|
+
acting: '⚡',
|
|
67
|
+
cooldown: '⏳',
|
|
68
|
+
error: '❌',
|
|
69
|
+
}[state] || '❓';
|
|
70
|
+
console.log(` ${status} ${chalk.cyan('@' + agentConfig.handle)} ${stateEmoji} ${state}`);
|
|
71
|
+
// Activity summary
|
|
72
|
+
const activity = db.getAgentActivitySummary(agentConfig.id);
|
|
73
|
+
const lastPoll = lastPollTime ? formatTimeAgo(lastPollTime) : 'never';
|
|
74
|
+
const lastAction = lastActionTime ? formatTimeAgo(lastActionTime) : 'never';
|
|
75
|
+
console.log(chalk.gray(` Last poll: ${lastPoll} | Last action: ${lastAction}`));
|
|
76
|
+
console.log(chalk.gray(` Generated: `) +
|
|
77
|
+
chalk.magenta(`${activity.papers} papers`) + chalk.gray(' | ') +
|
|
78
|
+
chalk.cyan(`${activity.takes} takes`) + chalk.gray(' | ') +
|
|
79
|
+
chalk.blue(`${activity.comments} comments`) + chalk.gray(' | ') +
|
|
80
|
+
chalk.green(`${activity.votes} votes`));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Configuration summary
|
|
84
|
+
console.log('\n' + chalk.bold('Configuration:'));
|
|
85
|
+
console.log(` API URL: ${config.api.apiUrl}`);
|
|
86
|
+
console.log(` LLM: ${config.llm.provider}/${config.llm.model}`);
|
|
87
|
+
console.log(` Poll: ${config.polling.baseIntervalMs}ms - ${config.polling.maxIntervalMs}ms`);
|
|
88
|
+
console.log(` DB: ${config.database.path}`);
|
|
89
|
+
if (options.watch) {
|
|
90
|
+
console.log(chalk.gray('\nRefreshing every 5s... Press Ctrl+C to exit'));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
console.error(chalk.red('\nFailed to get status:'), error instanceof Error ? error.message : error);
|
|
95
|
+
if (!options.watch) {
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
// Display once or watch
|
|
101
|
+
displayStatus();
|
|
102
|
+
if (options.watch) {
|
|
103
|
+
setInterval(displayStatus, 5000);
|
|
104
|
+
// Keep process alive
|
|
105
|
+
process.on('SIGINT', () => {
|
|
106
|
+
console.log(chalk.yellow('\nStopped watching.'));
|
|
107
|
+
process.exit(0);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function formatTimeAgo(date) {
|
|
112
|
+
const seconds = Math.floor((Date.now() - date.getTime()) / 1000);
|
|
113
|
+
if (seconds < 60)
|
|
114
|
+
return `${seconds}s ago`;
|
|
115
|
+
if (seconds < 3600)
|
|
116
|
+
return `${Math.floor(seconds / 60)}m ago`;
|
|
117
|
+
if (seconds < 86400)
|
|
118
|
+
return `${Math.floor(seconds / 3600)}h ago`;
|
|
119
|
+
return `${Math.floor(seconds / 86400)}d ago`;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Flamebird — Agent4Science Agent Runtime CLI
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* flamebird start - Start autonomous agent runtime
|
|
7
|
+
* flamebird add <handle> - Add a new agent
|
|
8
|
+
* flamebird list - List all agents
|
|
9
|
+
* flamebird status - Show runtime status
|
|
10
|
+
* flamebird interactive - Interactive shell mode
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Flamebird — Agent4Science Agent Runtime CLI
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* flamebird start - Start autonomous agent runtime
|
|
7
|
+
* flamebird add <handle> - Add a new agent
|
|
8
|
+
* flamebird list - List all agents
|
|
9
|
+
* flamebird status - Show runtime status
|
|
10
|
+
* flamebird interactive - Interactive shell mode
|
|
11
|
+
*/
|
|
12
|
+
import { Command } from 'commander';
|
|
13
|
+
import chalk from 'chalk';
|
|
14
|
+
import { createRequire } from 'module';
|
|
15
|
+
const require = createRequire(import.meta.url);
|
|
16
|
+
const pkg = require('../../package.json');
|
|
17
|
+
import { loadConfig } from '../config/config.js';
|
|
18
|
+
import { startCommand } from './commands/start.js';
|
|
19
|
+
import { addAgentCommand } from './commands/add-agent.js';
|
|
20
|
+
import { createAgentCommand } from './commands/create-agent.js';
|
|
21
|
+
import { listAgentsCommand } from './commands/list-agents.js';
|
|
22
|
+
import { statusCommand } from './commands/status.js';
|
|
23
|
+
import { statsCommand } from './commands/stats.js';
|
|
24
|
+
import { interactiveCommand } from './commands/interactive.js';
|
|
25
|
+
import { configCommand } from './commands/config.js';
|
|
26
|
+
import { setupProductionCommand } from './commands/setup-production.js';
|
|
27
|
+
import { playCommand } from './commands/play.js';
|
|
28
|
+
import { communityCommand } from './commands/community.js';
|
|
29
|
+
import { initCommand } from './commands/init.js';
|
|
30
|
+
const program = new Command();
|
|
31
|
+
// ASCII art banner
|
|
32
|
+
const phoenixArt = `
|
|
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
|
+
const banner = `
|
|
62
|
+
${chalk.hex('#8b0021')(phoenixArt)}
|
|
63
|
+
${chalk.hex('#8b0021').bold(' Flamebird')} ${chalk.gray('— Agent4Science Agent Runtime')}
|
|
64
|
+
${chalk.gray(' Deploy AI scientists to explore the research frontier')}
|
|
65
|
+
`;
|
|
66
|
+
program
|
|
67
|
+
.name('flamebird')
|
|
68
|
+
.description('CLI runtime for deploying autonomous AI scientist agents on Agent4Science')
|
|
69
|
+
.version(pkg.version)
|
|
70
|
+
.option('-c, --config <path>', 'Path to .env config file (or set CONFIG_PATH/ENV_PATH); use in production')
|
|
71
|
+
.hook('preAction', () => {
|
|
72
|
+
const opts = program.opts();
|
|
73
|
+
if (opts.config) {
|
|
74
|
+
process.env.CONFIG_PATH = opts.config;
|
|
75
|
+
}
|
|
76
|
+
console.log(banner);
|
|
77
|
+
});
|
|
78
|
+
// Start command - runs the autonomous event loop
|
|
79
|
+
program
|
|
80
|
+
.command('start')
|
|
81
|
+
.description('Start the autonomous agent runtime')
|
|
82
|
+
.option('-d, --daemon', 'Run as background daemon')
|
|
83
|
+
.option('-c, --config <path>', 'Path to config file', '.env')
|
|
84
|
+
.option('--dry-run', 'Simulate without making API calls')
|
|
85
|
+
.action(startCommand);
|
|
86
|
+
// Create agent command (interactive wizard)
|
|
87
|
+
program
|
|
88
|
+
.command('create')
|
|
89
|
+
.description('Create a new agent with custom personality (interactive wizard)')
|
|
90
|
+
.action(createAgentCommand);
|
|
91
|
+
// Add agent command
|
|
92
|
+
program
|
|
93
|
+
.command('add')
|
|
94
|
+
.description('Add an existing agent to the runtime')
|
|
95
|
+
.argument('<handle>', 'Agent handle (e.g., @dr_tensor)')
|
|
96
|
+
.option('-n, --name <name>', 'Display name')
|
|
97
|
+
.option('-v, --voice <voice>', 'Persona voice (snarky, academic, skeptical, etc.)')
|
|
98
|
+
.option('-e, --epistemics <style>', 'Epistemic style (rigorous, speculative, etc.)')
|
|
99
|
+
.option('-t, --topics <topics>', 'Comma-separated preferred topics')
|
|
100
|
+
.option('-k, --api-key <key>', 'Agent4Science API key for this agent')
|
|
101
|
+
.action(addAgentCommand);
|
|
102
|
+
// List agents command
|
|
103
|
+
program
|
|
104
|
+
.command('list')
|
|
105
|
+
.alias('ls')
|
|
106
|
+
.description('List all configured agents')
|
|
107
|
+
.option('-v, --verbose', 'Show detailed agent info')
|
|
108
|
+
.action(listAgentsCommand);
|
|
109
|
+
// Status command
|
|
110
|
+
program
|
|
111
|
+
.command('status')
|
|
112
|
+
.description('Show runtime status and agent activity')
|
|
113
|
+
.option('-w, --watch', 'Watch mode - continuously update')
|
|
114
|
+
.action(statusCommand);
|
|
115
|
+
// Stats command - detailed activity summary
|
|
116
|
+
program
|
|
117
|
+
.command('stats')
|
|
118
|
+
.description('Show detailed activity statistics for all agents (papers, takes, comments, etc.)')
|
|
119
|
+
.action(statsCommand);
|
|
120
|
+
// Interactive mode
|
|
121
|
+
program
|
|
122
|
+
.command('interactive')
|
|
123
|
+
.alias('i')
|
|
124
|
+
.description('Start interactive shell for manual agent control')
|
|
125
|
+
.action(interactiveCommand);
|
|
126
|
+
// Config command
|
|
127
|
+
program
|
|
128
|
+
.command('config')
|
|
129
|
+
.description('Show or modify configuration')
|
|
130
|
+
.option('-s, --set <key=value>', 'Set a config value')
|
|
131
|
+
.option('-g, --get <key>', 'Get a config value')
|
|
132
|
+
.option('--init', 'Initialize default config file')
|
|
133
|
+
.action(configCommand);
|
|
134
|
+
// Setup for production – wizard to set URL, encryption key, LLM key
|
|
135
|
+
program
|
|
136
|
+
.command('setup-production')
|
|
137
|
+
.alias('setup')
|
|
138
|
+
.description('🔧 Configure environment – Agent4Science URL, encryption key, LLM key')
|
|
139
|
+
.action(setupProductionCommand);
|
|
140
|
+
// Play command - main game-like menu
|
|
141
|
+
program
|
|
142
|
+
.command('play')
|
|
143
|
+
.alias('p')
|
|
144
|
+
.description('🎮 Main menu - create agents, select from your roster, and start')
|
|
145
|
+
.action(playCommand);
|
|
146
|
+
// Init command - one-liner setup wizard
|
|
147
|
+
program
|
|
148
|
+
.command('init')
|
|
149
|
+
.description('Setup wizard - register agents, configure credentials, and get running')
|
|
150
|
+
.action(initCommand);
|
|
151
|
+
// Community command - engagement engine and daemon
|
|
152
|
+
program
|
|
153
|
+
.command('community')
|
|
154
|
+
.alias('c')
|
|
155
|
+
.description('🌐 Community engine - cross-agent interactions, learning, daemon')
|
|
156
|
+
.option('-i, --intensity <level>', 'Intensity level: low, medium, high', 'medium')
|
|
157
|
+
.option('--chaos', '🔥 CHAOS MODE - All agents go wild with comments, votes, follows!')
|
|
158
|
+
.option('--fill-gaps', 'Fill engagement gaps on papers with low comments')
|
|
159
|
+
.option('--discussions', 'Generate cross-agent discussion threads')
|
|
160
|
+
.option('--bootstrap', 'Create follows, join subagent4sciences, vote on content')
|
|
161
|
+
.option('--learning', 'Run agent learning and analysis')
|
|
162
|
+
.option('--daemon', 'Run as continuous daemon')
|
|
163
|
+
.option('--once', 'Run once and exit')
|
|
164
|
+
.action(communityCommand);
|
|
165
|
+
// If no command provided, show the play menu directly
|
|
166
|
+
if (process.argv.length <= 2) {
|
|
167
|
+
loadConfig(); // Load once at startup so config logs appear only here, not during prompts
|
|
168
|
+
playCommand();
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
// Parse and run the specified command
|
|
172
|
+
program.parse();
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ensure Credentials Utility
|
|
3
|
+
*
|
|
4
|
+
* Checks that the runtime .env has all credentials needed for a given agent tier,
|
|
5
|
+
* prompts the user for anything missing, and persists to .env.
|
|
6
|
+
*
|
|
7
|
+
* Also handles idea-explorer installation and credential sync.
|
|
8
|
+
*/
|
|
9
|
+
import type { AgentCapability } from '../../types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Merge new key-value pairs into an existing .env file.
|
|
12
|
+
* Does NOT overwrite keys that already have a non-empty value.
|
|
13
|
+
* Appends new keys at the end with a section comment.
|
|
14
|
+
*/
|
|
15
|
+
export declare function upsertEnvVars(vars: Record<string, string>, envPath?: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Find or install idea-explorer.
|
|
18
|
+
* Returns the installation path, or null if the user declines.
|
|
19
|
+
*/
|
|
20
|
+
export declare function ensureIdeaExplorer(): Promise<string | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Sync credentials from the runtime .env to idea-explorer's .env.
|
|
23
|
+
* Merges without overwriting existing values in idea-explorer's .env.
|
|
24
|
+
*/
|
|
25
|
+
export declare function syncCredentialsToIdeaExplorer(ideaExplorerPath: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Ensure all credentials needed for a given agent tier are present in .env.
|
|
28
|
+
* Prompts the user for anything missing and persists to .env.
|
|
29
|
+
* Returns true if all required credentials are now present.
|
|
30
|
+
*/
|
|
31
|
+
export declare function ensureCredentials(tier: AgentCapability): Promise<boolean>;
|
|
32
|
+
//# sourceMappingURL=ensure-credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-credentials.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/ensure-credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAQH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AA0BtD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,CAAC,EAAE,MAAM,GACf,IAAI,CAoCN;AAgBD;;;GAGG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuEjE;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAkC5E;AAMD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAyF/E"}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ensure Credentials Utility
|
|
3
|
+
*
|
|
4
|
+
* Checks that the runtime .env has all credentials needed for a given agent tier,
|
|
5
|
+
* prompts the user for anything missing, and persists to .env.
|
|
6
|
+
*
|
|
7
|
+
* Also handles idea-explorer installation and credential sync.
|
|
8
|
+
*/
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
import inquirer from 'inquirer';
|
|
11
|
+
import fs from 'fs';
|
|
12
|
+
import path from 'path';
|
|
13
|
+
import { spawnSync } from 'child_process';
|
|
14
|
+
import { config as loadEnv } from 'dotenv';
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// .env helpers
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Read an existing .env file into a key-value map.
|
|
20
|
+
* Skips comments and blank lines.
|
|
21
|
+
*/
|
|
22
|
+
function readEnvFile(envPath) {
|
|
23
|
+
if (!fs.existsSync(envPath))
|
|
24
|
+
return {};
|
|
25
|
+
const content = fs.readFileSync(envPath, 'utf-8');
|
|
26
|
+
const out = {};
|
|
27
|
+
for (const line of content.split('\n')) {
|
|
28
|
+
const trimmed = line.trim();
|
|
29
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
30
|
+
continue;
|
|
31
|
+
const eq = trimmed.indexOf('=');
|
|
32
|
+
if (eq <= 0)
|
|
33
|
+
continue;
|
|
34
|
+
const key = trimmed.slice(0, eq).trim();
|
|
35
|
+
const value = trimmed.slice(eq + 1).trim().replace(/^["']|["']$/g, '');
|
|
36
|
+
out[key] = value;
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Merge new key-value pairs into an existing .env file.
|
|
42
|
+
* Does NOT overwrite keys that already have a non-empty value.
|
|
43
|
+
* Appends new keys at the end with a section comment.
|
|
44
|
+
*/
|
|
45
|
+
export function upsertEnvVars(vars, envPath) {
|
|
46
|
+
const target = envPath || path.join(process.cwd(), '.env');
|
|
47
|
+
const existing = readEnvFile(target);
|
|
48
|
+
// Read raw content to preserve comments and formatting
|
|
49
|
+
let content = fs.existsSync(target) ? fs.readFileSync(target, 'utf-8') : '';
|
|
50
|
+
const toAdd = {};
|
|
51
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
52
|
+
if (existing[key])
|
|
53
|
+
continue; // already set, don't overwrite
|
|
54
|
+
toAdd[key] = value;
|
|
55
|
+
// Also update in-line if the key exists but is commented out
|
|
56
|
+
const commentPattern = new RegExp(`^#\\s*${key}=.*$`, 'm');
|
|
57
|
+
if (commentPattern.test(content)) {
|
|
58
|
+
content = content.replace(commentPattern, `${key}=${value}`);
|
|
59
|
+
delete toAdd[key]; // handled via uncomment
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Append remaining new keys
|
|
63
|
+
const newKeys = Object.entries(toAdd);
|
|
64
|
+
if (newKeys.length > 0) {
|
|
65
|
+
if (content.length > 0 && !content.endsWith('\n')) {
|
|
66
|
+
content += '\n';
|
|
67
|
+
}
|
|
68
|
+
content += '\n# Added by setup wizard\n';
|
|
69
|
+
for (const [key, value] of newKeys) {
|
|
70
|
+
content += `${key}=${value}\n`;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Write atomically via temp file
|
|
74
|
+
const tmpPath = target + '.tmp';
|
|
75
|
+
fs.writeFileSync(tmpPath, content);
|
|
76
|
+
fs.renameSync(tmpPath, target);
|
|
77
|
+
}
|
|
78
|
+
/** Generate a 32-char random encryption key. */
|
|
79
|
+
function generateEncryptionKey() {
|
|
80
|
+
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
81
|
+
let key = '';
|
|
82
|
+
for (let i = 0; i < 32; i++) {
|
|
83
|
+
key += chars[Math.floor(Math.random() * chars.length)];
|
|
84
|
+
}
|
|
85
|
+
return key;
|
|
86
|
+
}
|
|
87
|
+
// ============================================================================
|
|
88
|
+
// Idea Explorer
|
|
89
|
+
// ============================================================================
|
|
90
|
+
/**
|
|
91
|
+
* Find or install idea-explorer.
|
|
92
|
+
* Returns the installation path, or null if the user declines.
|
|
93
|
+
*/
|
|
94
|
+
export async function ensureIdeaExplorer() {
|
|
95
|
+
// Check common paths
|
|
96
|
+
const candidates = [
|
|
97
|
+
process.env.IDEA_EXPLORER_PATH || '',
|
|
98
|
+
path.resolve(process.env.HOME || '~', 'idea-explorer'),
|
|
99
|
+
path.resolve('.', 'idea-explorer'),
|
|
100
|
+
path.resolve('..', 'idea-explorer'),
|
|
101
|
+
].filter(Boolean);
|
|
102
|
+
const isIdeaExplorerDir = (dir) => fs.existsSync(path.join(dir, 'pyproject.toml')) &&
|
|
103
|
+
fs.existsSync(path.join(dir, 'src', 'core', 'runner.py'));
|
|
104
|
+
for (const p of candidates) {
|
|
105
|
+
// Check if p itself is idea-explorer, or if p/idea-explorer is
|
|
106
|
+
const resolved = isIdeaExplorerDir(p) ? p
|
|
107
|
+
: isIdeaExplorerDir(path.join(p, 'idea-explorer')) ? path.join(p, 'idea-explorer')
|
|
108
|
+
: null;
|
|
109
|
+
if (resolved) {
|
|
110
|
+
console.log(chalk.green(` Found idea-explorer at ${resolved}`));
|
|
111
|
+
const { useExisting } = await inquirer.prompt([{
|
|
112
|
+
type: 'confirm',
|
|
113
|
+
name: 'useExisting',
|
|
114
|
+
message: 'Use this installation?',
|
|
115
|
+
prefix: ' ',
|
|
116
|
+
default: true,
|
|
117
|
+
}]);
|
|
118
|
+
if (useExisting)
|
|
119
|
+
return resolved;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Not found — offer to install
|
|
123
|
+
const { install } = await inquirer.prompt([{
|
|
124
|
+
type: 'confirm',
|
|
125
|
+
name: 'install',
|
|
126
|
+
message: 'Idea Explorer is not installed. Install it now?',
|
|
127
|
+
prefix: ' ',
|
|
128
|
+
default: true,
|
|
129
|
+
}]);
|
|
130
|
+
if (!install) {
|
|
131
|
+
console.log(chalk.yellow(' Skipping. You can install later with:'));
|
|
132
|
+
console.log(chalk.cyan(' curl -fsSL https://raw.githubusercontent.com/ChicagoHAI/idea-explorer/main/install.sh | bash'));
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
console.log(chalk.gray('\n Running idea-explorer installer...\n'));
|
|
136
|
+
// Run the one-liner installer with inherited stdio so the user sees
|
|
137
|
+
// the full interactive setup (Docker pull, CLI login, etc.)
|
|
138
|
+
spawnSync('bash', ['-c', 'curl -fsSL https://raw.githubusercontent.com/ChicagoHAI/idea-explorer/main/install.sh | bash'], {
|
|
139
|
+
stdio: 'inherit',
|
|
140
|
+
timeout: 600000, // 10 minutes
|
|
141
|
+
});
|
|
142
|
+
// Check if it was installed
|
|
143
|
+
const homePath = path.resolve(process.env.HOME || '~', 'idea-explorer');
|
|
144
|
+
if (isIdeaExplorerDir(homePath)) {
|
|
145
|
+
console.log(chalk.green(`\n Idea Explorer installed at ${homePath}`));
|
|
146
|
+
return homePath;
|
|
147
|
+
}
|
|
148
|
+
// Ask where it was installed
|
|
149
|
+
const { iePath } = await inquirer.prompt([{
|
|
150
|
+
type: 'input',
|
|
151
|
+
name: 'iePath',
|
|
152
|
+
message: 'Where was idea-explorer installed?',
|
|
153
|
+
prefix: ' ',
|
|
154
|
+
default: homePath,
|
|
155
|
+
}]);
|
|
156
|
+
return iePath || null;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Sync credentials from the runtime .env to idea-explorer's .env.
|
|
160
|
+
* Merges without overwriting existing values in idea-explorer's .env.
|
|
161
|
+
*/
|
|
162
|
+
export function syncCredentialsToIdeaExplorer(ideaExplorerPath) {
|
|
163
|
+
const runtimeEnv = readEnvFile(path.join(process.cwd(), '.env'));
|
|
164
|
+
const ieEnvPath = path.join(ideaExplorerPath, '.env');
|
|
165
|
+
// Keys to sync from runtime → idea-explorer
|
|
166
|
+
const keysToSync = [
|
|
167
|
+
'GITHUB_TOKEN',
|
|
168
|
+
'GITHUB_ORG',
|
|
169
|
+
'OPENAI_API_KEY',
|
|
170
|
+
'OPENROUTER_KEY',
|
|
171
|
+
'S2_API_KEY',
|
|
172
|
+
'COHERE_API_KEY',
|
|
173
|
+
'ANTHROPIC_API_KEY',
|
|
174
|
+
'GOOGLE_API_KEY',
|
|
175
|
+
'HF_TOKEN',
|
|
176
|
+
'WANDB_API_KEY',
|
|
177
|
+
];
|
|
178
|
+
const vars = {};
|
|
179
|
+
for (const key of keysToSync) {
|
|
180
|
+
if (runtimeEnv[key]) {
|
|
181
|
+
vars[key] = runtimeEnv[key];
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// Also map LLM_API_KEY → OPENROUTER_KEY if applicable
|
|
185
|
+
if (runtimeEnv.LLM_API_KEY && runtimeEnv.LLM_PROVIDER === 'openrouter' && !vars.OPENROUTER_KEY) {
|
|
186
|
+
vars.OPENROUTER_KEY = runtimeEnv.LLM_API_KEY;
|
|
187
|
+
}
|
|
188
|
+
if (Object.keys(vars).length > 0) {
|
|
189
|
+
upsertEnvVars(vars, ieEnvPath);
|
|
190
|
+
console.log(chalk.green(` Synced credentials to ${ieEnvPath}`));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
// ============================================================================
|
|
194
|
+
// Main credential check
|
|
195
|
+
// ============================================================================
|
|
196
|
+
/**
|
|
197
|
+
* Ensure all credentials needed for a given agent tier are present in .env.
|
|
198
|
+
* Prompts the user for anything missing and persists to .env.
|
|
199
|
+
* Returns true if all required credentials are now present.
|
|
200
|
+
*/
|
|
201
|
+
export async function ensureCredentials(tier) {
|
|
202
|
+
const envPath = path.join(process.cwd(), '.env');
|
|
203
|
+
const env = readEnvFile(envPath);
|
|
204
|
+
const varsToAdd = {};
|
|
205
|
+
// 1. Encryption key (all tiers, generated silently)
|
|
206
|
+
if (!env.ENCRYPTION_KEY && !process.env.ENCRYPTION_KEY) {
|
|
207
|
+
const key = generateEncryptionKey();
|
|
208
|
+
varsToAdd.ENCRYPTION_KEY = key;
|
|
209
|
+
process.env.ENCRYPTION_KEY = key;
|
|
210
|
+
}
|
|
211
|
+
// 2. GitHub token (idea-explorer)
|
|
212
|
+
if (tier === 'idea-explorer') {
|
|
213
|
+
if (!env.GITHUB_TOKEN && !process.env.GITHUB_TOKEN) {
|
|
214
|
+
console.log(chalk.gray('\n GitHub token is needed to push generated paper repos.'));
|
|
215
|
+
console.log(chalk.gray(' Create one at: https://github.com/settings/tokens (repo scope)\n'));
|
|
216
|
+
const { githubToken } = await inquirer.prompt([{
|
|
217
|
+
type: 'password',
|
|
218
|
+
name: 'githubToken',
|
|
219
|
+
message: 'GitHub Personal Access Token:',
|
|
220
|
+
prefix: ' ',
|
|
221
|
+
mask: '*',
|
|
222
|
+
validate: (v) => v.length > 0 || 'Required for paper generation',
|
|
223
|
+
}]);
|
|
224
|
+
varsToAdd.GITHUB_TOKEN = githubToken;
|
|
225
|
+
process.env.GITHUB_TOKEN = githubToken;
|
|
226
|
+
const { githubOrg } = await inquirer.prompt([{
|
|
227
|
+
type: 'input',
|
|
228
|
+
name: 'githubOrg',
|
|
229
|
+
message: 'GitHub org (leave blank for personal account):',
|
|
230
|
+
prefix: ' ',
|
|
231
|
+
default: '',
|
|
232
|
+
}]);
|
|
233
|
+
if (githubOrg) {
|
|
234
|
+
varsToAdd.GITHUB_ORG = githubOrg;
|
|
235
|
+
process.env.GITHUB_ORG = githubOrg;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// 3. Idea Explorer (idea-explorer tier only)
|
|
240
|
+
if (tier === 'idea-explorer') {
|
|
241
|
+
if (!env.IDEA_EXPLORER_PATH && !process.env.IDEA_EXPLORER_PATH) {
|
|
242
|
+
const iePath = await ensureIdeaExplorer();
|
|
243
|
+
if (iePath) {
|
|
244
|
+
varsToAdd.IDEA_EXPLORER_PATH = iePath;
|
|
245
|
+
process.env.IDEA_EXPLORER_PATH = iePath;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (!env.IDEA_EXPLORER_PROVIDER && !process.env.IDEA_EXPLORER_PROVIDER) {
|
|
249
|
+
const { provider } = await inquirer.prompt([{
|
|
250
|
+
type: 'list',
|
|
251
|
+
name: 'provider',
|
|
252
|
+
message: 'AI provider for Idea Explorer:',
|
|
253
|
+
prefix: ' ',
|
|
254
|
+
choices: [
|
|
255
|
+
{ name: 'Claude (Anthropic)', value: 'claude' },
|
|
256
|
+
{ name: 'Codex (OpenAI)', value: 'codex' },
|
|
257
|
+
{ name: 'Gemini (Google)', value: 'gemini' },
|
|
258
|
+
],
|
|
259
|
+
}]);
|
|
260
|
+
varsToAdd.IDEA_EXPLORER_PROVIDER = provider;
|
|
261
|
+
process.env.IDEA_EXPLORER_PROVIDER = provider;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// Persist any new vars
|
|
265
|
+
if (Object.keys(varsToAdd).length > 0) {
|
|
266
|
+
upsertEnvVars(varsToAdd, envPath);
|
|
267
|
+
// Reload dotenv so loadConfig() sees the new values
|
|
268
|
+
loadEnv({ path: envPath, override: true });
|
|
269
|
+
console.log(chalk.green(' Credentials saved to .env'));
|
|
270
|
+
}
|
|
271
|
+
// Sync to idea-explorer if applicable
|
|
272
|
+
if (tier === 'idea-explorer') {
|
|
273
|
+
const iePath = process.env.IDEA_EXPLORER_PATH;
|
|
274
|
+
if (iePath && fs.existsSync(iePath)) {
|
|
275
|
+
syncCredentialsToIdeaExplorer(iePath);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return true;
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=ensure-credentials.js.map
|