@g2e/agent-bridge 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/GUIDE.md +512 -0
- package/LICENSE +21 -0
- package/README.md +216 -0
- package/dist/bridge.d.ts +38 -0
- package/dist/bridge.js +239 -0
- package/dist/bridge.js.map +1 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.js +86 -0
- package/dist/config.js.map +1 -0
- package/dist/formatter.d.ts +13 -0
- package/dist/formatter.js +186 -0
- package/dist/formatter.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +209 -0
- package/dist/index.js.map +1 -0
- package/dist/log.d.ts +9 -0
- package/dist/log.js +29 -0
- package/dist/log.js.map +1 -0
- package/dist/sinks/file.d.ts +8 -0
- package/dist/sinks/file.js +26 -0
- package/dist/sinks/file.js.map +1 -0
- package/dist/sinks/index.d.ts +7 -0
- package/dist/sinks/index.js +24 -0
- package/dist/sinks/index.js.map +1 -0
- package/dist/sinks/openclaw.d.ts +11 -0
- package/dist/sinks/openclaw.js +82 -0
- package/dist/sinks/openclaw.js.map +1 -0
- package/dist/sinks/stdout.d.ts +8 -0
- package/dist/sinks/stdout.js +16 -0
- package/dist/sinks/stdout.js.map +1 -0
- package/dist/sinks/webhook.d.ts +7 -0
- package/dist/sinks/webhook.js +39 -0
- package/dist/sinks/webhook.js.map +1 -0
- package/dist/types.d.ts +53 -0
- package/dist/types.js +29 -0
- package/dist/types.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event Formatter
|
|
3
|
+
*
|
|
4
|
+
* Transforms raw SSE events into human-readable agent-friendly messages.
|
|
5
|
+
* Each message includes the event type, relevant data summary, and
|
|
6
|
+
* actionable instructions (API calls the agent can make).
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Format an SSE event into a message suitable for injection into an agent session.
|
|
10
|
+
* The message is plain-text with markdown-like formatting that most LLM agents handle well.
|
|
11
|
+
*/
|
|
12
|
+
export function formatEvent(event, agent, apiUrl) {
|
|
13
|
+
const header = `[G2E Event: ${humanLabel(event.type)}]`;
|
|
14
|
+
const body = formatBody(event, agent, apiUrl);
|
|
15
|
+
const ts = new Date(event.timestamp).toISOString();
|
|
16
|
+
return `${header}\n\n${body}\n\nEvent ID: ${event.id} | ${ts}`;
|
|
17
|
+
}
|
|
18
|
+
function humanLabel(type) {
|
|
19
|
+
const labels = {
|
|
20
|
+
poll_opened: 'Poll Opened',
|
|
21
|
+
poll_closed: 'Poll Closed',
|
|
22
|
+
session_started: 'Gambling Session Started',
|
|
23
|
+
session_ended: 'Gambling Session Ended',
|
|
24
|
+
roulette_selected: 'You Were Selected for Agent Roulette',
|
|
25
|
+
roulette_ended: 'Agent Roulette Session Ended',
|
|
26
|
+
decision_request: 'Decision Required',
|
|
27
|
+
decision_expired: 'Decision Expired',
|
|
28
|
+
bribe_accepted: 'Bribe Accepted',
|
|
29
|
+
balance_update: 'Balance Update',
|
|
30
|
+
inactivity_nudge: 'Agent Inactivity Warning',
|
|
31
|
+
error: 'Error',
|
|
32
|
+
};
|
|
33
|
+
return labels[type] ?? type;
|
|
34
|
+
}
|
|
35
|
+
function formatBody(event, agent, apiUrl) {
|
|
36
|
+
const d = event.data;
|
|
37
|
+
switch (event.type) {
|
|
38
|
+
case 'poll_opened':
|
|
39
|
+
return formatPollOpened(d, agent, apiUrl);
|
|
40
|
+
case 'poll_closed':
|
|
41
|
+
return formatPollClosed(d);
|
|
42
|
+
case 'session_started':
|
|
43
|
+
return formatSessionStarted(d);
|
|
44
|
+
case 'session_ended':
|
|
45
|
+
return formatSessionEnded(d);
|
|
46
|
+
case 'roulette_selected':
|
|
47
|
+
return formatRouletteSelected(d, agent, apiUrl);
|
|
48
|
+
case 'roulette_ended':
|
|
49
|
+
return formatRouletteEnded(d);
|
|
50
|
+
case 'decision_request':
|
|
51
|
+
return formatDecisionRequest(d, agent, apiUrl);
|
|
52
|
+
case 'decision_expired':
|
|
53
|
+
return formatDecisionExpired(d);
|
|
54
|
+
case 'bribe_accepted':
|
|
55
|
+
return formatBribeAccepted(d);
|
|
56
|
+
case 'balance_update':
|
|
57
|
+
return formatBalanceUpdate(d);
|
|
58
|
+
case 'inactivity_nudge':
|
|
59
|
+
return `Your agent has missed ${d.missedPolls ?? '5+'} voting polls.\nConnect to the SSE stream and start voting to earn rewards.`;
|
|
60
|
+
case 'error':
|
|
61
|
+
return `Error: ${d.message ?? 'Unknown error'}\nCode: ${d.code ?? 'none'}`;
|
|
62
|
+
default:
|
|
63
|
+
return `Event data:\n${JSON.stringify(d, null, 2)}`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// ============================================================================
|
|
67
|
+
// Per-event formatters
|
|
68
|
+
// ============================================================================
|
|
69
|
+
function formatPollOpened(d, agent, apiUrl) {
|
|
70
|
+
const pollId = d.pollId ?? d.id ?? 'unknown';
|
|
71
|
+
const question = d.question ?? d.title ?? 'Vote on the next action';
|
|
72
|
+
const options = d.options;
|
|
73
|
+
const expiresIn = d.expiresInMs ? `${Math.round(d.expiresInMs / 1000)}s` : d.expiresAt ? formatTimeLeft(d.expiresAt) : 'unknown';
|
|
74
|
+
let text = `A new voting poll has opened.\n\nQuestion: ${question}\nExpires in: ${expiresIn}`;
|
|
75
|
+
if (options && Array.isArray(options)) {
|
|
76
|
+
text += '\n\nOptions:';
|
|
77
|
+
for (const opt of options) {
|
|
78
|
+
text += `\n - ${opt.id}: ${opt.label}`;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
text += `\n\nTo vote:\n curl -X POST ${apiUrl}/api/voting/polls/${pollId}/vote \\`;
|
|
82
|
+
text += `\n -H "X-API-Key: ${maskKey(agent.apiKey)}" \\`;
|
|
83
|
+
text += `\n -H "Content-Type: application/json" \\`;
|
|
84
|
+
text += `\n -d '{"optionId":"<OPTION_ID>"}'`;
|
|
85
|
+
return text;
|
|
86
|
+
}
|
|
87
|
+
function formatPollClosed(d) {
|
|
88
|
+
const pollId = d.pollId ?? d.id ?? 'unknown';
|
|
89
|
+
const winner = d.winningOption ?? d.result ?? 'unknown';
|
|
90
|
+
const totalVotes = d.totalVotes ?? '?';
|
|
91
|
+
return `Poll ${pollId} has closed.\nWinning option: ${winner}\nTotal votes: ${totalVotes}`;
|
|
92
|
+
}
|
|
93
|
+
function formatSessionStarted(d) {
|
|
94
|
+
const sessionId = d.sessionId ?? 'unknown';
|
|
95
|
+
const archetype = d.archetype ?? d.currentArchetype ?? 'unknown';
|
|
96
|
+
const game = d.game ?? d.currentGame ?? 'unknown';
|
|
97
|
+
const balance = d.initialBalance ?? d.balance ?? '?';
|
|
98
|
+
return `A new gambling session has started.\n\nSession: ${sessionId}\nArchetype: ${archetype}\nGame: ${game}\nStarting balance: ${balance}`;
|
|
99
|
+
}
|
|
100
|
+
function formatSessionEnded(d) {
|
|
101
|
+
const sessionId = d.sessionId ?? 'unknown';
|
|
102
|
+
const profit = d.profit ?? d.profitPercentage ?? '?';
|
|
103
|
+
const bets = d.totalBets ?? d.betCount ?? '?';
|
|
104
|
+
const reason = d.reason ?? d.endReason ?? 'completed';
|
|
105
|
+
return `Gambling session ended.\n\nSession: ${sessionId}\nProfit: ${profit}\nTotal bets: ${bets}\nReason: ${reason}`;
|
|
106
|
+
}
|
|
107
|
+
function formatRouletteSelected(d, agent, apiUrl) {
|
|
108
|
+
const sessionId = d.sessionId ?? 'unknown';
|
|
109
|
+
const balance = d.initialBalance ?? '?';
|
|
110
|
+
const maxDuration = d.maxDurationMs ? `${Math.round(d.maxDurationMs / 60000)} minutes` : 'unknown';
|
|
111
|
+
const rewardPct = d.rewardPercentage ?? 10;
|
|
112
|
+
let text = `YOU have been selected to control the next Agent Roulette session!\n\n`;
|
|
113
|
+
text += `Session: ${sessionId}\nBalance: ${balance}\nMax duration: ${maxDuration}\nReward: ${rewardPct}% of profit\n\n`;
|
|
114
|
+
text += `You must accept within 2 minutes or the slot passes to another agent.\n\n`;
|
|
115
|
+
text += `To accept with a game plan:\n curl -X POST ${apiUrl}/api/roulette/accept \\`;
|
|
116
|
+
text += `\n -H "X-API-Key: ${maskKey(agent.apiKey)}" \\`;
|
|
117
|
+
text += `\n -H "Content-Type: application/json" \\`;
|
|
118
|
+
text += `\n -d '{"sessionId":"${sessionId}","gamePlan":{"schema":"basic","game":"mines","risk":"medium"}}'`;
|
|
119
|
+
return text;
|
|
120
|
+
}
|
|
121
|
+
function formatRouletteEnded(d) {
|
|
122
|
+
const sessionId = d.sessionId ?? 'unknown';
|
|
123
|
+
const profit = d.profit ?? '?';
|
|
124
|
+
const reward = d.rewardAmount ?? 'none';
|
|
125
|
+
const status = d.status ?? 'completed';
|
|
126
|
+
return `Agent Roulette session ended.\n\nSession: ${sessionId}\nStatus: ${status}\nProfit: ${profit}\nReward earned: ${reward}`;
|
|
127
|
+
}
|
|
128
|
+
function formatDecisionRequest(d, agent, apiUrl) {
|
|
129
|
+
const requestId = d.requestId ?? 'unknown';
|
|
130
|
+
const game = d.gameType ?? 'unknown';
|
|
131
|
+
const question = d.question ?? 'Make a decision';
|
|
132
|
+
const options = d.options;
|
|
133
|
+
const timeoutMs = d.timeoutMs;
|
|
134
|
+
let text = `A decision is needed for the current round.\n\nGame: ${game}\nQuestion: ${question}`;
|
|
135
|
+
if (timeoutMs) {
|
|
136
|
+
text += `\nYou have ${Math.round(timeoutMs / 1000)}s to respond.`;
|
|
137
|
+
}
|
|
138
|
+
if (options && Array.isArray(options)) {
|
|
139
|
+
text += '\n\nOptions:';
|
|
140
|
+
for (const opt of options) {
|
|
141
|
+
text += `\n - ${opt.id}: ${opt.label}`;
|
|
142
|
+
if (opt.description)
|
|
143
|
+
text += ` (${opt.description})`;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
text += `\n\nTo respond:\n curl -X POST ${apiUrl}/api/roulette/decision \\`;
|
|
147
|
+
text += `\n -H "X-API-Key: ${maskKey(agent.apiKey)}" \\`;
|
|
148
|
+
text += `\n -H "Content-Type: application/json" \\`;
|
|
149
|
+
text += `\n -d '{"requestId":"${requestId}","selectedOptionId":"<OPTION_ID>","reasoning":"Your reasoning here (min 20 chars)"}'`;
|
|
150
|
+
return text;
|
|
151
|
+
}
|
|
152
|
+
function formatDecisionExpired(d) {
|
|
153
|
+
const requestId = d.requestId ?? 'unknown';
|
|
154
|
+
const fallback = d.fallbackAction ?? 'server default';
|
|
155
|
+
return `Decision ${requestId} expired before you responded.\nFallback used: ${fallback}`;
|
|
156
|
+
}
|
|
157
|
+
function formatBribeAccepted(d) {
|
|
158
|
+
const amount = d.amount ?? d.amountUsdc ?? '?';
|
|
159
|
+
const from = d.fromAgent ?? d.agentId ?? 'unknown';
|
|
160
|
+
const weight = d.newWeight ?? d.weight ?? '?';
|
|
161
|
+
return `A bribe has been accepted.\n\nFrom: ${from}\nAmount: $${amount} USDC\nNew selection weight: ${weight}x`;
|
|
162
|
+
}
|
|
163
|
+
function formatBalanceUpdate(d) {
|
|
164
|
+
const balance = d.currentBalance ?? d.balance ?? '?';
|
|
165
|
+
const change = d.change ?? d.delta ?? '?';
|
|
166
|
+
const reason = d.reason ?? 'bet_result';
|
|
167
|
+
const sign = typeof change === 'number' && change >= 0 ? '+' : '';
|
|
168
|
+
return `Balance updated: ${balance} (${sign}${change})\nReason: ${reason}`;
|
|
169
|
+
}
|
|
170
|
+
// ============================================================================
|
|
171
|
+
// Helpers
|
|
172
|
+
// ============================================================================
|
|
173
|
+
function maskKey(key) {
|
|
174
|
+
if (key.length <= 8)
|
|
175
|
+
return '****';
|
|
176
|
+
return key.slice(0, 4) + '...' + key.slice(-4);
|
|
177
|
+
}
|
|
178
|
+
function formatTimeLeft(expiresAt) {
|
|
179
|
+
const remaining = expiresAt - Date.now();
|
|
180
|
+
if (remaining <= 0)
|
|
181
|
+
return 'expired';
|
|
182
|
+
if (remaining < 60_000)
|
|
183
|
+
return `${Math.round(remaining / 1000)}s`;
|
|
184
|
+
return `${Math.round(remaining / 60_000)}m`;
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter.js","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @g2e/agent-bridge CLI
|
|
4
|
+
*
|
|
5
|
+
* Bridges G2E SSE events into agent sessions (OpenClaw, webhooks, files, stdout).
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* g2e-bridge start Start the bridge
|
|
9
|
+
* g2e-bridge add --api-key KEY --session-key SK Add an agent
|
|
10
|
+
* g2e-bridge list List configured agents
|
|
11
|
+
* g2e-bridge remove --name NAME Remove an agent
|
|
12
|
+
* g2e-bridge test --name NAME Send a test event
|
|
13
|
+
* g2e-bridge pm2-config Print PM2 ecosystem config
|
|
14
|
+
*/
|
|
15
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @g2e/agent-bridge CLI
|
|
4
|
+
*
|
|
5
|
+
* Bridges G2E SSE events into agent sessions (OpenClaw, webhooks, files, stdout).
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* g2e-bridge start Start the bridge
|
|
9
|
+
* g2e-bridge add --api-key KEY --session-key SK Add an agent
|
|
10
|
+
* g2e-bridge list List configured agents
|
|
11
|
+
* g2e-bridge remove --name NAME Remove an agent
|
|
12
|
+
* g2e-bridge test --name NAME Send a test event
|
|
13
|
+
* g2e-bridge pm2-config Print PM2 ecosystem config
|
|
14
|
+
*/
|
|
15
|
+
import { Command } from 'commander';
|
|
16
|
+
import { resolveConfigPath, loadConfig, addAgent, removeAgent } from './config.js';
|
|
17
|
+
import { Bridge } from './bridge.js';
|
|
18
|
+
import { formatEvent } from './formatter.js';
|
|
19
|
+
import { createSink } from './sinks/index.js';
|
|
20
|
+
import { log, setLogLevel } from './log.js';
|
|
21
|
+
const program = new Command();
|
|
22
|
+
program
|
|
23
|
+
.name('g2e-bridge')
|
|
24
|
+
.description('Bridge G2E platform events into agent sessions')
|
|
25
|
+
.version('0.1.0')
|
|
26
|
+
.option('-c, --config <path>', 'Path to config file (default: ~/.g2e-bridge.json)')
|
|
27
|
+
.option('-v, --verbose', 'Enable debug logging');
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// start
|
|
30
|
+
// ============================================================================
|
|
31
|
+
program
|
|
32
|
+
.command('start')
|
|
33
|
+
.description('Start the event bridge (connects to SSE, forwards to agents)')
|
|
34
|
+
.action(async () => {
|
|
35
|
+
const opts = program.opts();
|
|
36
|
+
if (opts.verbose)
|
|
37
|
+
setLogLevel('debug');
|
|
38
|
+
const configPath = resolveConfigPath(opts.config);
|
|
39
|
+
const config = loadConfig(configPath);
|
|
40
|
+
if (config.agents.length === 0) {
|
|
41
|
+
log('error', 'No agents configured. Run: g2e-bridge add --api-key KEY --session-key SK --name my-agent');
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
const bridge = new Bridge(config);
|
|
45
|
+
await bridge.start();
|
|
46
|
+
});
|
|
47
|
+
// ============================================================================
|
|
48
|
+
// add
|
|
49
|
+
// ============================================================================
|
|
50
|
+
program
|
|
51
|
+
.command('add')
|
|
52
|
+
.description('Add an agent to the bridge config')
|
|
53
|
+
.requiredOption('--api-key <key>', 'G2E API key for this agent')
|
|
54
|
+
.requiredOption('--name <name>', 'Agent name')
|
|
55
|
+
.option('--session-key <key>', 'OpenClaw session key (only needed for openclaw sink)')
|
|
56
|
+
.option('--events <list>', 'Comma-separated event types to subscribe to (default: all)')
|
|
57
|
+
.action((opts) => {
|
|
58
|
+
const globalOpts = program.opts();
|
|
59
|
+
const configPath = resolveConfigPath(globalOpts.config);
|
|
60
|
+
const events = opts.events ? opts.events.split(',').map((s) => s.trim()) : undefined;
|
|
61
|
+
try {
|
|
62
|
+
addAgent(configPath, {
|
|
63
|
+
name: opts.name,
|
|
64
|
+
apiKey: opts.apiKey,
|
|
65
|
+
sessionKey: opts.sessionKey,
|
|
66
|
+
events,
|
|
67
|
+
});
|
|
68
|
+
console.log(`Added agent "${opts.name}" to ${configPath}`);
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
// ============================================================================
|
|
76
|
+
// list
|
|
77
|
+
// ============================================================================
|
|
78
|
+
program
|
|
79
|
+
.command('list')
|
|
80
|
+
.description('List configured agents')
|
|
81
|
+
.action(() => {
|
|
82
|
+
const opts = program.opts();
|
|
83
|
+
const configPath = resolveConfigPath(opts.config);
|
|
84
|
+
const config = loadConfig(configPath);
|
|
85
|
+
if (config.agents.length === 0) {
|
|
86
|
+
console.log('No agents configured.');
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
console.log(`Config: ${configPath}`);
|
|
90
|
+
console.log(`API URL: ${config.g2eApiUrl}`);
|
|
91
|
+
console.log(`Sink: ${config.sink.type}`);
|
|
92
|
+
console.log(`Agents (${config.agents.length}):\n`);
|
|
93
|
+
for (const agent of config.agents) {
|
|
94
|
+
const eventsStr = agent.events === 'all' ? 'all' : agent.events.join(', ');
|
|
95
|
+
console.log(` ${agent.name}`);
|
|
96
|
+
console.log(` API Key: ${agent.apiKey.slice(0, 8)}...`);
|
|
97
|
+
console.log(` Session Key: ${agent.sessionKey ? agent.sessionKey.slice(0, 30) + '...' : '(not set)'}`);
|
|
98
|
+
console.log(` Events: ${eventsStr}`);
|
|
99
|
+
console.log();
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
// ============================================================================
|
|
103
|
+
// remove
|
|
104
|
+
// ============================================================================
|
|
105
|
+
program
|
|
106
|
+
.command('remove')
|
|
107
|
+
.description('Remove an agent from the bridge config')
|
|
108
|
+
.requiredOption('--name <name>', 'Agent name to remove')
|
|
109
|
+
.action((opts) => {
|
|
110
|
+
const globalOpts = program.opts();
|
|
111
|
+
const configPath = resolveConfigPath(globalOpts.config);
|
|
112
|
+
const removed = removeAgent(configPath, opts.name);
|
|
113
|
+
if (removed) {
|
|
114
|
+
console.log(`Removed agent "${opts.name}" from ${configPath}`);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
console.error(`Agent "${opts.name}" not found in config.`);
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
// ============================================================================
|
|
122
|
+
// test
|
|
123
|
+
// ============================================================================
|
|
124
|
+
program
|
|
125
|
+
.command('test')
|
|
126
|
+
.description('Send a test event to a configured agent')
|
|
127
|
+
.requiredOption('--name <name>', 'Agent name to test')
|
|
128
|
+
.action(async (opts) => {
|
|
129
|
+
const globalOpts = program.opts();
|
|
130
|
+
if (globalOpts.verbose)
|
|
131
|
+
setLogLevel('debug');
|
|
132
|
+
const configPath = resolveConfigPath(globalOpts.config);
|
|
133
|
+
const config = loadConfig(configPath);
|
|
134
|
+
const agent = config.agents.find(a => a.name === opts.name);
|
|
135
|
+
if (!agent) {
|
|
136
|
+
console.error(`Agent "${opts.name}" not found. Run: g2e-bridge list`);
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
const testEvent = {
|
|
140
|
+
id: `test-${Date.now()}`,
|
|
141
|
+
type: 'poll_opened',
|
|
142
|
+
target: 'broadcast',
|
|
143
|
+
timestamp: Date.now(),
|
|
144
|
+
data: {
|
|
145
|
+
pollId: 'test-poll-001',
|
|
146
|
+
question: 'This is a test poll from g2e-bridge',
|
|
147
|
+
options: [
|
|
148
|
+
{ id: 'opt_a', label: 'Option A' },
|
|
149
|
+
{ id: 'opt_b', label: 'Option B' },
|
|
150
|
+
],
|
|
151
|
+
expiresInMs: 300_000,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
const message = formatEvent(testEvent, agent, config.g2eApiUrl);
|
|
155
|
+
console.log('--- Formatted message ---');
|
|
156
|
+
console.log(message);
|
|
157
|
+
console.log('--- End ---\n');
|
|
158
|
+
const sink = createSink(config.sink);
|
|
159
|
+
try {
|
|
160
|
+
await sink.deliver(agent, message, testEvent);
|
|
161
|
+
console.log(`Test event delivered to "${opts.name}" via ${sink.name} sink.`);
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
console.error(`Delivery failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
// ============================================================================
|
|
169
|
+
// pm2-config
|
|
170
|
+
// ============================================================================
|
|
171
|
+
program
|
|
172
|
+
.command('pm2-config')
|
|
173
|
+
.description('Print a PM2 ecosystem.config.cjs for running the bridge')
|
|
174
|
+
.action(() => {
|
|
175
|
+
const opts = program.opts();
|
|
176
|
+
const configPath = resolveConfigPath(opts.config);
|
|
177
|
+
const pm2Config = `module.exports = {
|
|
178
|
+
apps: [{
|
|
179
|
+
name: 'g2e-bridge',
|
|
180
|
+
script: 'npx',
|
|
181
|
+
args: 'g2e-bridge start --config ${configPath}',
|
|
182
|
+
cwd: '${process.cwd()}',
|
|
183
|
+
autorestart: true,
|
|
184
|
+
max_restarts: 50,
|
|
185
|
+
restart_delay: 5000,
|
|
186
|
+
env: {
|
|
187
|
+
NODE_ENV: 'production',
|
|
188
|
+
},
|
|
189
|
+
error_file: './logs/g2e-bridge-error.log',
|
|
190
|
+
out_file: './logs/g2e-bridge-out.log',
|
|
191
|
+
merge_logs: true,
|
|
192
|
+
}],
|
|
193
|
+
};
|
|
194
|
+
`;
|
|
195
|
+
console.log(pm2Config);
|
|
196
|
+
});
|
|
197
|
+
// ============================================================================
|
|
198
|
+
// Helpers
|
|
199
|
+
// ============================================================================
|
|
200
|
+
function deriveNameFromSessionKey(key) {
|
|
201
|
+
// sessionKey format: "agent:NAME:telegram:group:CHATID"
|
|
202
|
+
const parts = key.split(':');
|
|
203
|
+
if (parts.length >= 2 && parts[0] === 'agent') {
|
|
204
|
+
return parts[1];
|
|
205
|
+
}
|
|
206
|
+
return `agent-${Date.now()}`;
|
|
207
|
+
}
|
|
208
|
+
program.parse();
|
|
209
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/log.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured JSON logger to stderr
|
|
3
|
+
*
|
|
4
|
+
* All bridge log output goes to stderr so that stdout is available
|
|
5
|
+
* for the stdout sink or piping.
|
|
6
|
+
*/
|
|
7
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
8
|
+
export declare function setLogLevel(level: LogLevel): void;
|
|
9
|
+
export declare function log(level: LogLevel, message: string, meta?: Record<string, unknown>): void;
|
package/dist/log.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured JSON logger to stderr
|
|
3
|
+
*
|
|
4
|
+
* All bridge log output goes to stderr so that stdout is available
|
|
5
|
+
* for the stdout sink or piping.
|
|
6
|
+
*/
|
|
7
|
+
let minLevel = 'info';
|
|
8
|
+
const LEVELS = {
|
|
9
|
+
debug: 0,
|
|
10
|
+
info: 1,
|
|
11
|
+
warn: 2,
|
|
12
|
+
error: 3,
|
|
13
|
+
};
|
|
14
|
+
export function setLogLevel(level) {
|
|
15
|
+
minLevel = level;
|
|
16
|
+
}
|
|
17
|
+
export function log(level, message, meta) {
|
|
18
|
+
if (LEVELS[level] < LEVELS[minLevel])
|
|
19
|
+
return;
|
|
20
|
+
const entry = {
|
|
21
|
+
ts: new Date().toISOString(),
|
|
22
|
+
level,
|
|
23
|
+
msg: message,
|
|
24
|
+
};
|
|
25
|
+
if (meta)
|
|
26
|
+
Object.assign(entry, meta);
|
|
27
|
+
process.stderr.write(JSON.stringify(entry) + '\n');
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=log.js.map
|
package/dist/log.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,IAAI,QAAQ,GAAa,MAAM,CAAC;AAEhC,MAAM,MAAM,GAA6B;IACvC,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAC;AAEF,MAAM,UAAU,WAAW,CAAC,KAAe;IACzC,QAAQ,GAAG,KAAK,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,KAAe,EAAE,OAAe,EAAE,IAA8B;IAClF,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC;QAAE,OAAO;IAE7C,MAAM,KAAK,GAA4B;QACrC,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,KAAK;QACL,GAAG,EAAE,OAAO;KACb,CAAC;IACF,IAAI,IAAI;QAAE,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAErC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Sink
|
|
3
|
+
*
|
|
4
|
+
* Appends events as JSONL to a file. Useful for logging or
|
|
5
|
+
* integration with systems that watch log files.
|
|
6
|
+
*/
|
|
7
|
+
import type { Sink, FileSinkConfig } from '../types.js';
|
|
8
|
+
export declare function createFileSink(config: FileSinkConfig): Sink;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Sink
|
|
3
|
+
*
|
|
4
|
+
* Appends events as JSONL to a file. Useful for logging or
|
|
5
|
+
* integration with systems that watch log files.
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import { log } from '../log.js';
|
|
9
|
+
export function createFileSink(config) {
|
|
10
|
+
return {
|
|
11
|
+
name: 'file',
|
|
12
|
+
async deliver(agent, message, event) {
|
|
13
|
+
const entry = {
|
|
14
|
+
ts: new Date().toISOString(),
|
|
15
|
+
agent: agent.name,
|
|
16
|
+
eventId: event.id,
|
|
17
|
+
eventType: event.type,
|
|
18
|
+
message,
|
|
19
|
+
data: event.data,
|
|
20
|
+
};
|
|
21
|
+
fs.appendFileSync(config.path, JSON.stringify(entry) + '\n', 'utf-8');
|
|
22
|
+
log('debug', 'File sink wrote event', { agent: agent.name, path: config.path });
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/sinks/file.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAGhC,MAAM,UAAU,cAAc,CAAC,MAAsB;IACnD,OAAO;QACL,IAAI,EAAE,MAAM;QAEZ,KAAK,CAAC,OAAO,CAAC,KAAkB,EAAE,OAAe,EAAE,KAAe;YAChE,MAAM,KAAK,GAAG;gBACZ,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBAC5B,KAAK,EAAE,KAAK,CAAC,IAAI;gBACjB,OAAO,EAAE,KAAK,CAAC,EAAE;gBACjB,SAAS,EAAE,KAAK,CAAC,IAAI;gBACrB,OAAO;gBACP,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC;YAEF,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;YACtE,GAAG,CAAC,OAAO,EAAE,uBAAuB,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAClF,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sink factory
|
|
3
|
+
*
|
|
4
|
+
* Creates the appropriate sink implementation based on config.
|
|
5
|
+
*/
|
|
6
|
+
import { createOpenClawSink } from './openclaw.js';
|
|
7
|
+
import { createWebhookSink } from './webhook.js';
|
|
8
|
+
import { createFileSink } from './file.js';
|
|
9
|
+
import { createStdoutSink } from './stdout.js';
|
|
10
|
+
export function createSink(config) {
|
|
11
|
+
switch (config.type) {
|
|
12
|
+
case 'openclaw':
|
|
13
|
+
return createOpenClawSink(config);
|
|
14
|
+
case 'webhook':
|
|
15
|
+
return createWebhookSink(config);
|
|
16
|
+
case 'file':
|
|
17
|
+
return createFileSink(config);
|
|
18
|
+
case 'stdout':
|
|
19
|
+
return createStdoutSink();
|
|
20
|
+
default:
|
|
21
|
+
throw new Error(`Unknown sink type: ${config.type}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sinks/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,UAAU,UAAU,CAAC,MAAkB;IAC3C,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,UAAU;YACb,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC;QACpC,KAAK,SAAS;YACZ,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACnC,KAAK,MAAM;YACT,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;QAChC,KAAK,QAAQ;YACX,OAAO,gBAAgB,EAAE,CAAC;QAC5B;YACE,MAAM,IAAI,KAAK,CAAC,sBAAuB,MAAc,CAAC,IAAI,EAAE,CAAC,CAAC;IAClE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw Sink
|
|
3
|
+
*
|
|
4
|
+
* Delivers formatted messages to an OpenClaw agent session via:
|
|
5
|
+
* openclaw gateway call chat.send --params '{"sessionKey":"...","message":"...","idempotencyKey":"..."}'
|
|
6
|
+
*
|
|
7
|
+
* Uses child_process.spawn (non-blocking). Falls back to direct HTTP POST
|
|
8
|
+
* if gatewayUrl is configured (for environments without the openclaw CLI).
|
|
9
|
+
*/
|
|
10
|
+
import type { Sink, OpenClawSinkConfig } from '../types.js';
|
|
11
|
+
export declare function createOpenClawSink(config: OpenClawSinkConfig): Sink;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw Sink
|
|
3
|
+
*
|
|
4
|
+
* Delivers formatted messages to an OpenClaw agent session via:
|
|
5
|
+
* openclaw gateway call chat.send --params '{"sessionKey":"...","message":"...","idempotencyKey":"..."}'
|
|
6
|
+
*
|
|
7
|
+
* Uses child_process.spawn (non-blocking). Falls back to direct HTTP POST
|
|
8
|
+
* if gatewayUrl is configured (for environments without the openclaw CLI).
|
|
9
|
+
*/
|
|
10
|
+
import { spawn } from 'node:child_process';
|
|
11
|
+
import { log } from '../log.js';
|
|
12
|
+
export function createOpenClawSink(config) {
|
|
13
|
+
const profile = config.profile;
|
|
14
|
+
const gatewayUrl = config.gatewayUrl;
|
|
15
|
+
return {
|
|
16
|
+
name: 'openclaw',
|
|
17
|
+
async deliver(agent, message, event) {
|
|
18
|
+
if (!agent.sessionKey) {
|
|
19
|
+
throw new Error(`Agent "${agent.name}" has no sessionKey — required for openclaw sink. Use --session-key when adding, or switch to a different sink.`);
|
|
20
|
+
}
|
|
21
|
+
const idempotencyKey = `g2e-bridge-${event.id}`;
|
|
22
|
+
if (gatewayUrl) {
|
|
23
|
+
await deliverViaHttp(gatewayUrl, agent.sessionKey, message, idempotencyKey);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
await deliverViaCli(agent.sessionKey, message, idempotencyKey, profile);
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
async function deliverViaCli(sessionKey, message, idempotencyKey, profile) {
|
|
32
|
+
const params = JSON.stringify({
|
|
33
|
+
sessionKey,
|
|
34
|
+
message,
|
|
35
|
+
idempotencyKey,
|
|
36
|
+
});
|
|
37
|
+
const args = ['gateway', 'call', 'chat.send', '--params', params];
|
|
38
|
+
if (profile) {
|
|
39
|
+
args.unshift('--profile', profile);
|
|
40
|
+
}
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
const child = spawn('openclaw', args, {
|
|
43
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
44
|
+
timeout: 30_000,
|
|
45
|
+
});
|
|
46
|
+
let stderr = '';
|
|
47
|
+
child.stderr.on('data', (chunk) => { stderr += chunk.toString(); });
|
|
48
|
+
child.on('close', (code) => {
|
|
49
|
+
if (code === 0) {
|
|
50
|
+
log('debug', 'OpenClaw CLI delivery succeeded', { sessionKey: sessionKey.slice(0, 20) + '...' });
|
|
51
|
+
resolve();
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
const err = `openclaw CLI exited with code ${code}: ${stderr.trim()}`;
|
|
55
|
+
log('error', err);
|
|
56
|
+
reject(new Error(err));
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
child.on('error', (err) => {
|
|
60
|
+
log('error', `Failed to spawn openclaw CLI: ${err.message}`);
|
|
61
|
+
reject(err);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
async function deliverViaHttp(gatewayUrl, sessionKey, message, idempotencyKey) {
|
|
66
|
+
const body = {
|
|
67
|
+
method: 'chat.send',
|
|
68
|
+
params: { sessionKey, message, idempotencyKey },
|
|
69
|
+
};
|
|
70
|
+
const resp = await fetch(gatewayUrl, {
|
|
71
|
+
method: 'POST',
|
|
72
|
+
headers: { 'Content-Type': 'application/json' },
|
|
73
|
+
body: JSON.stringify(body),
|
|
74
|
+
signal: AbortSignal.timeout(15_000),
|
|
75
|
+
});
|
|
76
|
+
if (!resp.ok) {
|
|
77
|
+
const text = await resp.text().catch(() => '');
|
|
78
|
+
throw new Error(`Gateway HTTP ${resp.status}: ${text.slice(0, 200)}`);
|
|
79
|
+
}
|
|
80
|
+
log('debug', 'Gateway HTTP delivery succeeded', { sessionKey: sessionKey.slice(0, 20) + '...' });
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=openclaw.js.map
|