@elizaos/plugin-tunnel 2.0.3-beta.6 → 2.0.3-beta.7
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/dist/__tests__/TunnelTestSuite.d.ts +6 -0
- package/dist/__tests__/TunnelTestSuite.d.ts.map +1 -0
- package/dist/__tests__/TunnelTestSuite.js +47 -0
- package/dist/__tests__/TunnelTestSuite.js.map +1 -0
- package/dist/actions/get-tunnel-status.d.ts +3 -0
- package/dist/actions/get-tunnel-status.d.ts.map +1 -0
- package/dist/actions/get-tunnel-status.js +43 -0
- package/dist/actions/get-tunnel-status.js.map +1 -0
- package/dist/actions/start-tunnel.d.ts +3 -0
- package/dist/actions/start-tunnel.d.ts.map +1 -0
- package/dist/actions/start-tunnel.js +102 -0
- package/dist/actions/start-tunnel.js.map +1 -0
- package/dist/actions/stop-tunnel.d.ts +3 -0
- package/dist/actions/stop-tunnel.d.ts.map +1 -0
- package/dist/actions/stop-tunnel.js +41 -0
- package/dist/actions/stop-tunnel.js.map +1 -0
- package/dist/actions/tunnel.d.ts +20 -0
- package/dist/actions/tunnel.d.ts.map +1 -0
- package/dist/actions/tunnel.js +142 -0
- package/dist/actions/tunnel.js.map +1 -0
- package/dist/environment.d.ts +18 -0
- package/dist/environment.d.ts.map +1 -0
- package/dist/environment.js +66 -0
- package/dist/environment.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/tunnel-state.d.ts +12 -0
- package/dist/providers/tunnel-state.d.ts.map +1 -0
- package/dist/providers/tunnel-state.js +43 -0
- package/dist/providers/tunnel-state.js.map +1 -0
- package/dist/services/LocalTunnelService.d.ts +37 -0
- package/dist/services/LocalTunnelService.d.ts.map +1 -0
- package/dist/services/LocalTunnelService.js +186 -0
- package/dist/services/LocalTunnelService.js.map +1 -0
- package/dist/types.d.ts +47 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +34 -0
- package/dist/types.js.map +1 -0
- package/package.json +4 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TunnelTestSuite.d.ts","sourceRoot":"","sources":["../../src/__tests__/TunnelTestSuite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,QAAQ,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAKxE,qBAAa,eAAgB,YAAW,SAAS;IAC/C,IAAI,SAAY;IAChB,KAAK,EAAE,QAAQ,EAAE,CAqCf;CACH"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { tunnelAction } from '../actions/tunnel';
|
|
2
|
+
import { tunnelStateProvider } from '../providers/tunnel-state';
|
|
3
|
+
import { LocalTunnelService } from '../services/LocalTunnelService';
|
|
4
|
+
export class TunnelTestSuite {
|
|
5
|
+
name = 'tunnel';
|
|
6
|
+
tests = [
|
|
7
|
+
{
|
|
8
|
+
name: 'LocalTunnelService — service-type contract',
|
|
9
|
+
fn: (_runtime) => {
|
|
10
|
+
if (LocalTunnelService.serviceType !== 'tunnel') {
|
|
11
|
+
throw new Error('LocalTunnelService.serviceType must be "tunnel"');
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: 'tunnelAction — name and op enum',
|
|
17
|
+
fn: (_runtime) => {
|
|
18
|
+
if (tunnelAction.name !== 'TUNNEL') {
|
|
19
|
+
throw new Error(`tunnelAction.name must be "TUNNEL", got ${tunnelAction.name}`);
|
|
20
|
+
}
|
|
21
|
+
const opParam = tunnelAction.parameters?.find((p) => p.name === 'op');
|
|
22
|
+
if (!opParam)
|
|
23
|
+
throw new Error('tunnelAction must declare an `op` parameter');
|
|
24
|
+
const enumVals = opParam.schema?.enum;
|
|
25
|
+
if (!Array.isArray(enumVals))
|
|
26
|
+
throw new Error('op parameter must declare a string enum');
|
|
27
|
+
for (const expected of ['start', 'stop', 'status']) {
|
|
28
|
+
if (!enumVals.includes(expected)) {
|
|
29
|
+
throw new Error(`op enum missing "${expected}"`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'TUNNEL_STATE provider — name and shape',
|
|
36
|
+
fn: (_runtime) => {
|
|
37
|
+
if (tunnelStateProvider.name !== 'TUNNEL_STATE') {
|
|
38
|
+
throw new Error(`tunnelStateProvider.name must be "TUNNEL_STATE"`);
|
|
39
|
+
}
|
|
40
|
+
if (typeof tunnelStateProvider.get !== 'function') {
|
|
41
|
+
throw new Error('tunnelStateProvider must define get()');
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=TunnelTestSuite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TunnelTestSuite.js","sourceRoot":"","sources":["../../src/__tests__/TunnelTestSuite.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEpE,MAAM,OAAO,eAAe;IAC1B,IAAI,GAAG,QAAQ,CAAC;IAChB,KAAK,GAAe;QAClB;YACE,IAAI,EAAE,4CAA4C;YAClD,EAAE,EAAE,CAAC,QAAuB,EAAE,EAAE;gBAC9B,IAAI,kBAAkB,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;oBAChD,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;gBACrE,CAAC;YACH,CAAC;SACF;QACD;YACE,IAAI,EAAE,iCAAiC;YACvC,EAAE,EAAE,CAAC,QAAuB,EAAE,EAAE;gBAC9B,IAAI,YAAY,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACnC,MAAM,IAAI,KAAK,CAAC,2CAA2C,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;gBAClF,CAAC;gBACD,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;gBACtE,IAAI,CAAC,OAAO;oBAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;gBAC7E,MAAM,QAAQ,GAAI,OAAO,CAAC,MAA2C,EAAE,IAAI,CAAC;gBAC5E,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;oBAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;gBACzF,KAAK,MAAM,QAAQ,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;oBACnD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;wBACjC,MAAM,IAAI,KAAK,CAAC,oBAAoB,QAAQ,GAAG,CAAC,CAAC;oBACnD,CAAC;gBACH,CAAC;YACH,CAAC;SACF;QACD;YACE,IAAI,EAAE,wCAAwC;YAC9C,EAAE,EAAE,CAAC,QAAuB,EAAE,EAAE;gBAC9B,IAAI,mBAAmB,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;oBAChD,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;gBACrE,CAAC;gBACD,IAAI,OAAO,mBAAmB,CAAC,GAAG,KAAK,UAAU,EAAE,CAAC;oBAClD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;gBAC3D,CAAC;YACH,CAAC;SACF;KACF,CAAC;CACH"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type ActionResult, type HandlerCallback, type IAgentRuntime, type Memory, type State } from '@elizaos/core';
|
|
2
|
+
export declare function handleGetTunnelStatus(runtime: IAgentRuntime, _message?: Memory, _state?: State, _options?: Record<string, unknown>, callback?: HandlerCallback): Promise<ActionResult>;
|
|
3
|
+
//# sourceMappingURL=get-tunnel-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-tunnel-status.d.ts","sourceRoot":"","sources":["../../src/actions/get-tunnel-status.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,MAAM,EACX,KAAK,KAAK,EACX,MAAM,eAAe,CAAC;AAavB,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,aAAa,EACtB,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,KAAK,EACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,QAAQ,CAAC,EAAE,eAAe,GACzB,OAAO,CAAC,YAAY,CAAC,CAiCvB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { elizaLogger, } from '@elizaos/core';
|
|
2
|
+
import { getTunnelService } from '../types';
|
|
3
|
+
function formatUptime(startedAt) {
|
|
4
|
+
const ms = Date.now() - startedAt.getTime();
|
|
5
|
+
const minutes = Math.floor(ms / 60_000);
|
|
6
|
+
const hours = Math.floor(minutes / 60);
|
|
7
|
+
if (hours > 0) {
|
|
8
|
+
return `${hours} hour${hours === 1 ? '' : 's'}, ${minutes % 60} minute${minutes % 60 === 1 ? '' : 's'}`;
|
|
9
|
+
}
|
|
10
|
+
return `${minutes} minute${minutes === 1 ? '' : 's'}`;
|
|
11
|
+
}
|
|
12
|
+
export async function handleGetTunnelStatus(runtime, _message, _state, _options, callback) {
|
|
13
|
+
const tunnelService = getTunnelService(runtime);
|
|
14
|
+
if (!tunnelService) {
|
|
15
|
+
if (callback) {
|
|
16
|
+
await callback({ text: 'Tunnel service is not available.' });
|
|
17
|
+
}
|
|
18
|
+
return { success: false, error: 'tunnel service unavailable' };
|
|
19
|
+
}
|
|
20
|
+
elizaLogger.info('[get-tunnel-status] reading status');
|
|
21
|
+
const status = tunnelService.getStatus();
|
|
22
|
+
const uptime = status.startedAt ? formatUptime(status.startedAt) : 'N/A';
|
|
23
|
+
const responseText = status.active
|
|
24
|
+
? `✅ tunnel active (${status.provider}).\n\nURL: ${status.url}\nLocal port: ${status.port}\nUptime: ${uptime}`
|
|
25
|
+
: '❌ No active tunnel. Say "start tunnel on port [PORT]" to start one.';
|
|
26
|
+
if (callback) {
|
|
27
|
+
await callback({ text: responseText });
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
success: true,
|
|
31
|
+
text: responseText,
|
|
32
|
+
data: {
|
|
33
|
+
action: 'tunnel_status',
|
|
34
|
+
active: status.active,
|
|
35
|
+
url: status.url ?? '',
|
|
36
|
+
port: status.port ?? 0,
|
|
37
|
+
provider: status.provider,
|
|
38
|
+
backend: status.backend ?? '',
|
|
39
|
+
uptime,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=get-tunnel-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-tunnel-status.js","sourceRoot":"","sources":["../../src/actions/get-tunnel-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,GAKZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,SAAS,YAAY,CAAC,SAAe;IACnC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACvC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,OAAO,GAAG,KAAK,QAAQ,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,OAAO,GAAG,EAAE,UAAU,OAAO,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IAC1G,CAAC;IACD,OAAO,GAAG,OAAO,UAAU,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAAsB,EACtB,QAAiB,EACjB,MAAc,EACd,QAAkC,EAClC,QAA0B;IAE1B,MAAM,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAChD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,QAAQ,CAAC,EAAE,IAAI,EAAE,kCAAkC,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC;IACjE,CAAC;IAED,WAAW,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAEzE,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM;QAChC,CAAC,CAAC,oBAAoB,MAAM,CAAC,QAAQ,cAAc,MAAM,CAAC,GAAG,iBAAiB,MAAM,CAAC,IAAI,aAAa,MAAM,EAAE;QAC9G,CAAC,CAAC,qEAAqE,CAAC;IAE1E,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,QAAQ,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,OAAO;QACL,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,MAAM,EAAE,eAAe;YACvB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE;YACrB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC;YACtB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;YAC7B,MAAM;SACP;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type ActionResult, type HandlerCallback, type IAgentRuntime, type Memory, type State } from '@elizaos/core';
|
|
2
|
+
export declare function handleStartTunnel(runtime: IAgentRuntime, message: Memory, _state?: State, options?: Record<string, unknown>, callback?: HandlerCallback): Promise<ActionResult>;
|
|
3
|
+
//# sourceMappingURL=start-tunnel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-tunnel.d.ts","sourceRoot":"","sources":["../../src/actions/start-tunnel.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,MAAM,EAEX,KAAK,KAAK,EACX,MAAM,eAAe,CAAC;AA0CvB,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,KAAK,EACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,QAAQ,CAAC,EAAE,eAAe,GACzB,OAAO,CAAC,YAAY,CAAC,CAiEvB"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { elizaLogger, ModelType, } from '@elizaos/core';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getTunnelService } from '../types';
|
|
4
|
+
const portPayloadSchema = z.object({
|
|
5
|
+
port: z.union([z.number(), z.string().regex(/^\d+$/)]).transform((value) => {
|
|
6
|
+
const num = typeof value === 'string' ? Number.parseInt(value, 10) : value;
|
|
7
|
+
return num;
|
|
8
|
+
}),
|
|
9
|
+
});
|
|
10
|
+
const PORT_PROMPT_TEMPLATE = `Respond with a JSON object containing the port number to start the tunnel on.
|
|
11
|
+
The user said: "{{userMessage}}"
|
|
12
|
+
|
|
13
|
+
Extract the port number from their message, or use the default port 3000 if not specified.
|
|
14
|
+
|
|
15
|
+
Response format:
|
|
16
|
+
\`\`\`json
|
|
17
|
+
{ "port": 3000 }
|
|
18
|
+
\`\`\``;
|
|
19
|
+
const DEFAULT_PORT = 3000;
|
|
20
|
+
function isValidPort(value) {
|
|
21
|
+
return Number.isInteger(value) && value >= 1 && value <= 65535;
|
|
22
|
+
}
|
|
23
|
+
function parsePort(value) {
|
|
24
|
+
try {
|
|
25
|
+
const parsed = JSON.parse(value);
|
|
26
|
+
const result = portPayloadSchema.safeParse(parsed);
|
|
27
|
+
if (result.success && isValidPort(result.data.port))
|
|
28
|
+
return result.data.port;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// fall through
|
|
32
|
+
}
|
|
33
|
+
const match = value.match(/\b(\d{1,5})\b/);
|
|
34
|
+
const captured = match?.[1];
|
|
35
|
+
if (!captured)
|
|
36
|
+
return DEFAULT_PORT;
|
|
37
|
+
const num = Number.parseInt(captured, 10);
|
|
38
|
+
return isValidPort(num) ? num : DEFAULT_PORT;
|
|
39
|
+
}
|
|
40
|
+
export async function handleStartTunnel(runtime, message, _state, options, callback) {
|
|
41
|
+
const tunnelService = getTunnelService(runtime);
|
|
42
|
+
if (!tunnelService) {
|
|
43
|
+
if (callback) {
|
|
44
|
+
await callback({
|
|
45
|
+
text: 'Tunnel service is not available. Configure plugin-tunnel, plugin-elizacloud, or plugin-ngrok.',
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return { success: false, error: 'tunnel service unavailable' };
|
|
49
|
+
}
|
|
50
|
+
if (tunnelService.isActive()) {
|
|
51
|
+
if (callback) {
|
|
52
|
+
await callback({
|
|
53
|
+
text: 'Tunnel is already active. Stop the existing tunnel before starting a new one.',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return { success: false, error: 'tunnel already active' };
|
|
57
|
+
}
|
|
58
|
+
elizaLogger.info('[start-tunnel] starting tunnel');
|
|
59
|
+
let port;
|
|
60
|
+
const explicitPort = options?.port;
|
|
61
|
+
if (typeof explicitPort === 'number' && isValidPort(explicitPort)) {
|
|
62
|
+
port = explicitPort;
|
|
63
|
+
}
|
|
64
|
+
else if (typeof explicitPort === 'string' && /^\d+$/.test(explicitPort)) {
|
|
65
|
+
const parsed = Number.parseInt(explicitPort, 10);
|
|
66
|
+
if (isValidPort(parsed))
|
|
67
|
+
port = parsed;
|
|
68
|
+
}
|
|
69
|
+
if (explicitPort !== undefined && port === undefined) {
|
|
70
|
+
const message = 'Invalid tunnel port. Port must be an integer between 1 and 65535.';
|
|
71
|
+
if (callback)
|
|
72
|
+
await callback({ text: message });
|
|
73
|
+
return { success: false, error: 'invalid tunnel port' };
|
|
74
|
+
}
|
|
75
|
+
if (port === undefined) {
|
|
76
|
+
const userMessage = message.content.text ?? '';
|
|
77
|
+
const portResponse = await runtime.useModel(ModelType.TEXT_SMALL, {
|
|
78
|
+
prompt: PORT_PROMPT_TEMPLATE.replace('{{userMessage}}', userMessage),
|
|
79
|
+
temperature: 0.3,
|
|
80
|
+
});
|
|
81
|
+
port = parsePort(String(portResponse));
|
|
82
|
+
}
|
|
83
|
+
const url = await tunnelService.startTunnel(port);
|
|
84
|
+
const publicUrl = typeof url === 'string' ? url : tunnelService.getUrl();
|
|
85
|
+
const status = tunnelService.getStatus();
|
|
86
|
+
if (callback) {
|
|
87
|
+
await callback({
|
|
88
|
+
text: `Tunnel started (${status.provider}).\n\nURL: ${publicUrl ?? 'unknown'}\nLocal port: ${port}`,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
success: true,
|
|
93
|
+
text: `Tunnel started on port ${port}`,
|
|
94
|
+
data: {
|
|
95
|
+
action: 'tunnel_started',
|
|
96
|
+
tunnelUrl: publicUrl ?? '',
|
|
97
|
+
port,
|
|
98
|
+
provider: status.provider,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=start-tunnel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-tunnel.js","sourceRoot":"","sources":["../../src/actions/start-tunnel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type ActionResult, type HandlerCallback, type IAgentRuntime, type Memory, type State } from '@elizaos/core';
|
|
2
|
+
export declare function handleStopTunnel(runtime: IAgentRuntime, _message?: Memory, _state?: State, _options?: Record<string, unknown>, callback?: HandlerCallback): Promise<ActionResult>;
|
|
3
|
+
//# sourceMappingURL=stop-tunnel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop-tunnel.d.ts","sourceRoot":"","sources":["../../src/actions/stop-tunnel.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,MAAM,EACX,KAAK,KAAK,EACX,MAAM,eAAe,CAAC;AAGvB,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,aAAa,EACtB,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,KAAK,EACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,QAAQ,CAAC,EAAE,eAAe,GACzB,OAAO,CAAC,YAAY,CAAC,CAyCvB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { elizaLogger, } from '@elizaos/core';
|
|
2
|
+
import { getTunnelService } from '../types';
|
|
3
|
+
export async function handleStopTunnel(runtime, _message, _state, _options, callback) {
|
|
4
|
+
const tunnelService = getTunnelService(runtime);
|
|
5
|
+
if (!tunnelService) {
|
|
6
|
+
if (callback) {
|
|
7
|
+
await callback({ text: 'Tunnel service is not available.' });
|
|
8
|
+
}
|
|
9
|
+
return { success: false, error: 'tunnel service unavailable' };
|
|
10
|
+
}
|
|
11
|
+
if (!tunnelService.isActive()) {
|
|
12
|
+
elizaLogger.warn('[stop-tunnel] no active tunnel to stop');
|
|
13
|
+
if (callback) {
|
|
14
|
+
await callback({ text: 'No tunnel is currently running.' });
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
success: true,
|
|
18
|
+
text: 'no active tunnel',
|
|
19
|
+
data: { action: 'tunnel_not_active' },
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const status = tunnelService.getStatus();
|
|
23
|
+
const previousUrl = status.url;
|
|
24
|
+
const previousPort = status.port;
|
|
25
|
+
await tunnelService.stopTunnel();
|
|
26
|
+
if (callback) {
|
|
27
|
+
await callback({
|
|
28
|
+
text: `Tunnel stopped.\n\nWas running on port: ${previousPort}\nPrevious URL: ${previousUrl}`,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
success: true,
|
|
33
|
+
text: `Tunnel stopped (was on port ${previousPort})`,
|
|
34
|
+
data: {
|
|
35
|
+
action: 'tunnel_stopped',
|
|
36
|
+
previousUrl: previousUrl ?? '',
|
|
37
|
+
previousPort: previousPort ?? 0,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=stop-tunnel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop-tunnel.js","sourceRoot":"","sources":["../../src/actions/stop-tunnel.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,GAKZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,OAAsB,EACtB,QAAiB,EACjB,MAAc,EACd,QAAkC,EAClC,QAA0B;IAE1B,MAAM,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAChD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,QAAQ,CAAC,EAAE,IAAI,EAAE,kCAAkC,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC;IACjE,CAAC;IAED,IAAI,CAAC,aAAa,CAAC,QAAQ,EAAE,EAAE,CAAC;QAC9B,WAAW,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QAC3D,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,QAAQ,CAAC,EAAE,IAAI,EAAE,iCAAiC,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,kBAAkB;YACxB,IAAI,EAAE,EAAE,MAAM,EAAE,mBAAmB,EAAE;SACtC,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,EAAE,CAAC;IACzC,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC;IAC/B,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC;IAEjC,MAAM,aAAa,CAAC,UAAU,EAAE,CAAC;IAEjC,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,QAAQ,CAAC;YACb,IAAI,EAAE,2CAA2C,YAAY,mBAAmB,WAAW,EAAE;SAC9F,CAAC,CAAC;IACL,CAAC;IACD,OAAO;QACL,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,+BAA+B,YAAY,GAAG;QACpD,IAAI,EAAE;YACJ,MAAM,EAAE,gBAAgB;YACxB,WAAW,EAAE,WAAW,IAAI,EAAE;YAC9B,YAAY,EAAE,YAAY,IAAI,CAAC;SAChC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module tunnel
|
|
3
|
+
* @description Single dispatcher action that fans out to the active
|
|
4
|
+
* tunnel-service implementation. The action's name is `TUNNEL`; concrete
|
|
5
|
+
* providers such as local Tailscale, Eliza Cloud headscale, and ngrok only
|
|
6
|
+
* register the service backend.
|
|
7
|
+
*
|
|
8
|
+
* Sub-ops (selected via the `action` parameter-enum):
|
|
9
|
+
* - start -> handleStartTunnel (optional `port`, defaults to 3000)
|
|
10
|
+
* - stop -> handleStopTunnel (no parameters)
|
|
11
|
+
* - status -> handleGetTunnelStatus (no parameters)
|
|
12
|
+
*
|
|
13
|
+
* The handler accepts both call shapes:
|
|
14
|
+
* 1. `{ action, ...subParams }`
|
|
15
|
+
* 2. `{ parameters: { action, parameters: { ...subParams } } }` (LLM extraction)
|
|
16
|
+
*/
|
|
17
|
+
import type { Action } from '@elizaos/core';
|
|
18
|
+
export declare const tunnelAction: Action;
|
|
19
|
+
export default tunnelAction;
|
|
20
|
+
//# sourceMappingURL=tunnel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel.d.ts","sourceRoot":"","sources":["../../src/actions/tunnel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EACV,MAAM,EAMP,MAAM,eAAe,CAAC;AA2CvB,eAAO,MAAM,YAAY,EAAE,MAoG1B,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module tunnel
|
|
3
|
+
* @description Single dispatcher action that fans out to the active
|
|
4
|
+
* tunnel-service implementation. The action's name is `TUNNEL`; concrete
|
|
5
|
+
* providers such as local Tailscale, Eliza Cloud headscale, and ngrok only
|
|
6
|
+
* register the service backend.
|
|
7
|
+
*
|
|
8
|
+
* Sub-ops (selected via the `action` parameter-enum):
|
|
9
|
+
* - start -> handleStartTunnel (optional `port`, defaults to 3000)
|
|
10
|
+
* - stop -> handleStopTunnel (no parameters)
|
|
11
|
+
* - status -> handleGetTunnelStatus (no parameters)
|
|
12
|
+
*
|
|
13
|
+
* The handler accepts both call shapes:
|
|
14
|
+
* 1. `{ action, ...subParams }`
|
|
15
|
+
* 2. `{ parameters: { action, parameters: { ...subParams } } }` (LLM extraction)
|
|
16
|
+
*/
|
|
17
|
+
import { getTunnelService } from '../types';
|
|
18
|
+
import { handleGetTunnelStatus } from './get-tunnel-status';
|
|
19
|
+
import { handleStartTunnel } from './start-tunnel';
|
|
20
|
+
import { handleStopTunnel } from './stop-tunnel';
|
|
21
|
+
const SUPPORTED_OPS = ['start', 'stop', 'status'];
|
|
22
|
+
function pickRecord(value) {
|
|
23
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
24
|
+
? value
|
|
25
|
+
: undefined;
|
|
26
|
+
}
|
|
27
|
+
function resolveDispatch(options) {
|
|
28
|
+
if (!options) {
|
|
29
|
+
return { action: null, subOptions: {} };
|
|
30
|
+
}
|
|
31
|
+
const nested = pickRecord(options.parameters);
|
|
32
|
+
const actionSource = nested ?? options;
|
|
33
|
+
const rawAction = actionSource.action;
|
|
34
|
+
const action = typeof rawAction === 'string' ? rawAction.toLowerCase() : null;
|
|
35
|
+
let subOptions;
|
|
36
|
+
if (nested) {
|
|
37
|
+
const innerParams = pickRecord(nested.parameters);
|
|
38
|
+
if (innerParams) {
|
|
39
|
+
subOptions = { ...innerParams };
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const { action: _omitAction, parameters: _omitParams, ...rest } = nested;
|
|
43
|
+
subOptions = rest;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
const { action: _omitAction, ...rest } = options;
|
|
48
|
+
subOptions = rest;
|
|
49
|
+
}
|
|
50
|
+
return { action, subOptions };
|
|
51
|
+
}
|
|
52
|
+
export const tunnelAction = {
|
|
53
|
+
name: 'TUNNEL',
|
|
54
|
+
similes: ['OPEN_TUNNEL', 'CREATE_TUNNEL', 'CLOSE_TUNNEL', 'CHECK_TUNNEL', 'TUNNEL_INFO'],
|
|
55
|
+
description: 'Tunnel operations dispatched by `action`: start, stop, status. The `start` action accepts an optional `port` (defaults to 3000); `stop` and `status` take no parameters. Backed by whichever tunnel plugin is active (local Tailscale CLI, Eliza Cloud headscale, or ngrok).',
|
|
56
|
+
parameters: [
|
|
57
|
+
{
|
|
58
|
+
name: 'action',
|
|
59
|
+
description: 'Which tunnel sub-operation to run. One of: start, stop, status.',
|
|
60
|
+
required: true,
|
|
61
|
+
schema: {
|
|
62
|
+
type: 'string',
|
|
63
|
+
enum: [...SUPPORTED_OPS],
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: 'parameters',
|
|
68
|
+
description: 'Parameters forwarded to the selected sub-op. For `start`, optionally `{ port: number }`. `stop` and `status` take no parameters.',
|
|
69
|
+
required: false,
|
|
70
|
+
schema: { type: 'object' },
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
validate: async (runtime) => {
|
|
74
|
+
return Boolean(getTunnelService(runtime));
|
|
75
|
+
},
|
|
76
|
+
handler: async (runtime, message, state, options, callback) => {
|
|
77
|
+
const { action, subOptions } = resolveDispatch(options);
|
|
78
|
+
if (!action) {
|
|
79
|
+
const err = `TUNNEL requires action=start|stop|status`;
|
|
80
|
+
if (callback)
|
|
81
|
+
await callback({ text: err });
|
|
82
|
+
return { success: false, error: err };
|
|
83
|
+
}
|
|
84
|
+
switch (action) {
|
|
85
|
+
case 'start':
|
|
86
|
+
return handleStartTunnel(runtime, message, state, subOptions, callback);
|
|
87
|
+
case 'stop':
|
|
88
|
+
return handleStopTunnel(runtime, message, state, subOptions, callback);
|
|
89
|
+
case 'status':
|
|
90
|
+
return handleGetTunnelStatus(runtime, message, state, subOptions, callback);
|
|
91
|
+
default: {
|
|
92
|
+
const err = `Unknown TUNNEL action "${action}". Supported: ${SUPPORTED_OPS.join(', ')}`;
|
|
93
|
+
if (callback)
|
|
94
|
+
await callback({ text: err });
|
|
95
|
+
return { success: false, error: err };
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
examples: [
|
|
100
|
+
[
|
|
101
|
+
{
|
|
102
|
+
name: '{{user1}}',
|
|
103
|
+
content: { text: 'Start a tunnel on port 8080' },
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: '{{agentName}}',
|
|
107
|
+
content: {
|
|
108
|
+
text: 'Tunnel started (tailscale).\n\nURL: https://device.tail-scale.ts.net\nLocal port: 8080',
|
|
109
|
+
actions: ['TUNNEL'],
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
[
|
|
114
|
+
{
|
|
115
|
+
name: '{{user1}}',
|
|
116
|
+
content: { text: 'Stop the tunnel' },
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: '{{agentName}}',
|
|
120
|
+
content: {
|
|
121
|
+
text: 'Tunnel stopped.',
|
|
122
|
+
actions: ['TUNNEL'],
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
[
|
|
127
|
+
{
|
|
128
|
+
name: '{{user1}}',
|
|
129
|
+
content: { text: 'What is the tunnel status?' },
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: '{{agentName}}',
|
|
133
|
+
content: {
|
|
134
|
+
text: '✅ tunnel active (tailscale).',
|
|
135
|
+
actions: ['TUNNEL'],
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
],
|
|
140
|
+
};
|
|
141
|
+
export default tunnelAction;
|
|
142
|
+
//# sourceMappingURL=tunnel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../../src/actions/tunnel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAUH,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAE3D,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAChE,CAAC,CAAE,KAAiC;QACpC,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,SAAS,eAAe,CAAC,OAA4C;IAInE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IAC1C,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC9C,MAAM,YAAY,GAAG,MAAM,IAAI,OAAO,CAAC;IACvC,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC;IACtC,MAAM,MAAM,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAE9E,IAAI,UAAmC,CAAC;IACxC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAClD,IAAI,WAAW,EAAE,CAAC;YAChB,UAAU,GAAG,EAAE,GAAG,WAAW,EAAE,CAAC;QAClC,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;YACzE,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;QACjD,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAW;IAClC,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,CAAC,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,CAAC;IACxF,WAAW,EACT,8QAA8Q;IAEhR,UAAU,EAAE;QACV;YACE,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,iEAAiE;YAC9E,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,GAAG,aAAa,CAAC;aACzB;SACF;QACD;YACE,IAAI,EAAE,YAAY;YAClB,WAAW,EACT,kIAAkI;YACpI,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SAC3B;KACF;IAED,QAAQ,EAAE,KAAK,EAAE,OAAsB,EAAoB,EAAE;QAC3D,OAAO,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,OAAO,EAAE,KAAK,EACZ,OAAsB,EACtB,OAAe,EACf,KAAa,EACb,OAAiC,EACjC,QAA0B,EACH,EAAE;QACzB,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;QAExD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,GAAG,0CAA0C,CAAC;YACvD,IAAI,QAAQ;gBAAE,MAAM,QAAQ,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;YAC5C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QACxC,CAAC;QAED,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,OAAO;gBACV,OAAO,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC1E,KAAK,MAAM;gBACT,OAAO,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;YACzE,KAAK,QAAQ;gBACX,OAAO,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC9E,OAAO,CAAC,CAAC,CAAC;gBACR,MAAM,GAAG,GAAG,0BAA0B,MAAM,iBAAiB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxF,IAAI,QAAQ;oBAAE,MAAM,QAAQ,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC5C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;YACxC,CAAC;QACH,CAAC;IACH,CAAC;IAED,QAAQ,EAAE;QACR;YACE;gBACE,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,EAAE,IAAI,EAAE,6BAA6B,EAAE;aACjD;YACD;gBACE,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,wFAAwF;oBAC9F,OAAO,EAAE,CAAC,QAAQ,CAAC;iBACpB;aACF;SACF;QACD;YACE;gBACE,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE;aACrC;YACD;gBACE,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,iBAAiB;oBACvB,OAAO,EAAE,CAAC,QAAQ,CAAC;iBACpB;aACF;SACF;QACD;YACE;gBACE,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,EAAE,IAAI,EAAE,4BAA4B,EAAE;aAChD;YACD;gBACE,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,8BAA8B;oBACpC,OAAO,EAAE,CAAC,QAAQ,CAAC;iBACpB;aACF;SACF;KACF;CACF,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IAgentRuntime } from '@elizaos/core';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
/**
|
|
4
|
+
* Local-CLI tunnel config. The cloud-backed (headscale) flavor lives in
|
|
5
|
+
* `@elizaos/plugin-elizacloud`; this package only configures the local
|
|
6
|
+
* `tailscale` CLI.
|
|
7
|
+
*
|
|
8
|
+
* `TUNNEL_*` env vars are the canonical names. `TAILSCALE_*` are accepted
|
|
9
|
+
* as aliases for one release window so existing `.env` files keep working.
|
|
10
|
+
*/
|
|
11
|
+
export declare const tunnelEnvSchema: z.ZodObject<{
|
|
12
|
+
TUNNEL_TAGS: z.ZodDefault<z.ZodPipe<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>, z.ZodTransform<string[], string | string[] | undefined>>>;
|
|
13
|
+
TUNNEL_FUNNEL: z.ZodDefault<z.ZodPipe<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>, z.ZodTransform<boolean, string | boolean | undefined>>>;
|
|
14
|
+
TUNNEL_DEFAULT_PORT: z.ZodDefault<z.ZodPipe<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>, z.ZodTransform<number, string | number | undefined>>>;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
export type TunnelConfig = z.infer<typeof tunnelEnvSchema>;
|
|
17
|
+
export declare function validateTunnelConfig(runtime: IAgentRuntime): Promise<TunnelConfig>;
|
|
18
|
+
//# sourceMappingURL=environment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;;;;iBA8B1B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAwB3D,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAOxF"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Local-CLI tunnel config. The cloud-backed (headscale) flavor lives in
|
|
4
|
+
* `@elizaos/plugin-elizacloud`; this package only configures the local
|
|
5
|
+
* `tailscale` CLI.
|
|
6
|
+
*
|
|
7
|
+
* `TUNNEL_*` env vars are the canonical names. `TAILSCALE_*` are accepted
|
|
8
|
+
* as aliases for one release window so existing `.env` files keep working.
|
|
9
|
+
*/
|
|
10
|
+
export const tunnelEnvSchema = z.object({
|
|
11
|
+
TUNNEL_TAGS: z
|
|
12
|
+
.union([z.string(), z.array(z.string())])
|
|
13
|
+
.optional()
|
|
14
|
+
.transform((value) => {
|
|
15
|
+
if (Array.isArray(value))
|
|
16
|
+
return value.map((tag) => tag.trim()).filter((tag) => tag.length > 0);
|
|
17
|
+
if (typeof value === 'string' && value.length > 0)
|
|
18
|
+
return value
|
|
19
|
+
.split(',')
|
|
20
|
+
.map((tag) => tag.trim())
|
|
21
|
+
.filter((tag) => tag.length > 0);
|
|
22
|
+
return ['tag:eliza-tunnel'];
|
|
23
|
+
})
|
|
24
|
+
.default(['tag:eliza-tunnel']),
|
|
25
|
+
TUNNEL_FUNNEL: z
|
|
26
|
+
.union([z.string(), z.boolean()])
|
|
27
|
+
.optional()
|
|
28
|
+
.transform((value) => value === true || value === 'true' || value === '1')
|
|
29
|
+
.default(false),
|
|
30
|
+
TUNNEL_DEFAULT_PORT: z
|
|
31
|
+
.union([z.string(), z.number()])
|
|
32
|
+
.optional()
|
|
33
|
+
.transform((value) => {
|
|
34
|
+
if (value === undefined || value === '')
|
|
35
|
+
return 3000;
|
|
36
|
+
const num = typeof value === 'string' && /^\d+$/.test(value) ? Number(value) : value;
|
|
37
|
+
if (typeof num !== 'number' || !Number.isInteger(num) || num <= 0 || num > 65535)
|
|
38
|
+
return 3000;
|
|
39
|
+
return num;
|
|
40
|
+
})
|
|
41
|
+
.default(3000),
|
|
42
|
+
});
|
|
43
|
+
function readSetting(runtime, key) {
|
|
44
|
+
const value = runtime.getSetting(key);
|
|
45
|
+
if (value === null || value === undefined)
|
|
46
|
+
return undefined;
|
|
47
|
+
return String(value);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Read `TUNNEL_<KEY>` first, then fall back to the legacy `TAILSCALE_<KEY>`.
|
|
51
|
+
*/
|
|
52
|
+
function readWithLegacy(runtime, newKey, legacyKey) {
|
|
53
|
+
return (readSetting(runtime, newKey) ??
|
|
54
|
+
readSetting(runtime, legacyKey) ??
|
|
55
|
+
process.env[newKey] ??
|
|
56
|
+
process.env[legacyKey]);
|
|
57
|
+
}
|
|
58
|
+
export async function validateTunnelConfig(runtime) {
|
|
59
|
+
const config = {
|
|
60
|
+
TUNNEL_TAGS: readWithLegacy(runtime, 'TUNNEL_TAGS', 'TAILSCALE_TAGS'),
|
|
61
|
+
TUNNEL_FUNNEL: readWithLegacy(runtime, 'TUNNEL_FUNNEL', 'TAILSCALE_FUNNEL'),
|
|
62
|
+
TUNNEL_DEFAULT_PORT: readWithLegacy(runtime, 'TUNNEL_DEFAULT_PORT', 'TAILSCALE_DEFAULT_PORT'),
|
|
63
|
+
};
|
|
64
|
+
return tunnelEnvSchema.parse(config);
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=environment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Plugin } from '@elizaos/core';
|
|
2
|
+
/**
|
|
3
|
+
* Local Tailscale-CLI tunnel plugin.
|
|
4
|
+
*
|
|
5
|
+
* Registers `serviceType = "tunnel"` ONLY when:
|
|
6
|
+
* 1. No other tunnel service has already claimed the slot (first-active-wins
|
|
7
|
+
* across plugin-tunnel, plugin-elizacloud, plugin-ngrok), AND
|
|
8
|
+
* 2. The `tailscale` CLI is on PATH.
|
|
9
|
+
*
|
|
10
|
+
* The Eliza Cloud (headscale) tunnel lives in `@elizaos/plugin-elizacloud`.
|
|
11
|
+
* Ngrok lives in `@elizaos/plugin-ngrok`. Enable as many as you like — only
|
|
12
|
+
* one will bind.
|
|
13
|
+
*/
|
|
14
|
+
export declare const tunnelPlugin: Plugin;
|
|
15
|
+
export default tunnelPlugin;
|
|
16
|
+
export { tunnelAction } from './actions/tunnel';
|
|
17
|
+
export { type TunnelConfig, validateTunnelConfig } from './environment';
|
|
18
|
+
export { tunnelStateProvider } from './providers/tunnel-state';
|
|
19
|
+
export { checkTailscaleInstalled, LocalTunnelService } from './services/LocalTunnelService';
|
|
20
|
+
export { getTunnelService, type ITunnelService, type TunnelProvider, type TunnelStatus, tunnelSlotIsFree, } from './types';
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,MAAM,EAA8B,MAAM,eAAe,CAAC;AAOrF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,EAAE,MAwB1B,CAAC;AAEF,eAAe,YAAY,CAAC;AAE5B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,KAAK,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EACL,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,gBAAgB,GACjB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { elizaLogger, promoteSubactionsToActions } from '@elizaos/core';
|
|
2
|
+
import { TunnelTestSuite } from './__tests__/TunnelTestSuite';
|
|
3
|
+
import { tunnelAction } from './actions/tunnel';
|
|
4
|
+
import { tunnelStateProvider } from './providers/tunnel-state';
|
|
5
|
+
import { checkTailscaleInstalled, LocalTunnelService } from './services/LocalTunnelService';
|
|
6
|
+
import { tunnelSlotIsFree } from './types';
|
|
7
|
+
/**
|
|
8
|
+
* Local Tailscale-CLI tunnel plugin.
|
|
9
|
+
*
|
|
10
|
+
* Registers `serviceType = "tunnel"` ONLY when:
|
|
11
|
+
* 1. No other tunnel service has already claimed the slot (first-active-wins
|
|
12
|
+
* across plugin-tunnel, plugin-elizacloud, plugin-ngrok), AND
|
|
13
|
+
* 2. The `tailscale` CLI is on PATH.
|
|
14
|
+
*
|
|
15
|
+
* The Eliza Cloud (headscale) tunnel lives in `@elizaos/plugin-elizacloud`.
|
|
16
|
+
* Ngrok lives in `@elizaos/plugin-ngrok`. Enable as many as you like — only
|
|
17
|
+
* one will bind.
|
|
18
|
+
*/
|
|
19
|
+
export const tunnelPlugin = {
|
|
20
|
+
name: 'tunnel',
|
|
21
|
+
description: 'Local Tailscale-CLI tunnel backend (serve / funnel). Coexists with plugin-elizacloud and plugin-ngrok via first-active-wins registration.',
|
|
22
|
+
actions: [...promoteSubactionsToActions(tunnelAction)],
|
|
23
|
+
providers: [tunnelStateProvider],
|
|
24
|
+
tests: [new TunnelTestSuite()],
|
|
25
|
+
init: async (_config, runtime) => {
|
|
26
|
+
if (!tunnelSlotIsFree(runtime)) {
|
|
27
|
+
elizaLogger.info('[plugin-tunnel] another tunnel service already registered — skipping LocalTunnelService');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const installed = await checkTailscaleInstalled();
|
|
31
|
+
if (!installed) {
|
|
32
|
+
elizaLogger.info('[plugin-tunnel] tailscale CLI not found on PATH — skipping LocalTunnelService');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
elizaLogger.info('[plugin-tunnel] registering LocalTunnelService for serviceType="tunnel"');
|
|
36
|
+
await runtime.registerService(LocalTunnelService);
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
export default tunnelPlugin;
|
|
40
|
+
export { tunnelAction } from './actions/tunnel';
|
|
41
|
+
export { validateTunnelConfig } from './environment';
|
|
42
|
+
export { tunnelStateProvider } from './providers/tunnel-state';
|
|
43
|
+
// Public surface for consumers and sibling tunnel plugins.
|
|
44
|
+
export { checkTailscaleInstalled, LocalTunnelService } from './services/LocalTunnelService';
|
|
45
|
+
export { getTunnelService, tunnelSlotIsFree, } from './types';
|
|
46
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAe,0BAA0B,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,YAAY,GAAW;IAClC,IAAI,EAAE,QAAQ;IACd,WAAW,EACT,2IAA2I;IAC7I,OAAO,EAAE,CAAC,GAAG,0BAA0B,CAAC,YAAY,CAAC,CAAC;IACtD,SAAS,EAAE,CAAC,mBAAmB,CAAC;IAChC,KAAK,EAAE,CAAC,IAAI,eAAe,EAAE,CAAC;IAC9B,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;QAC/B,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;YAC/B,WAAW,CAAC,IAAI,CACd,yFAAyF,CAC1F,CAAC;YACF,OAAO;QACT,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,uBAAuB,EAAE,CAAC;QAClD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,WAAW,CAAC,IAAI,CACd,+EAA+E,CAChF,CAAC;YACF,OAAO;QACT,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;QAC5F,MAAM,OAAO,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC;IACpD,CAAC;CACF,CAAC;AAEF,eAAe,YAAY,CAAC;AAE5B,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAqB,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,2DAA2D;AAC3D,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EACL,gBAAgB,EAIhB,gBAAgB,GACjB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Provider } from '@elizaos/core';
|
|
2
|
+
/**
|
|
3
|
+
* Surfaces the active tunnel's status into the model's state. Renders a
|
|
4
|
+
* one-line text summary and exposes the raw status object via `data`.
|
|
5
|
+
*
|
|
6
|
+
* Backend-agnostic — works with whichever tunnel implementation
|
|
7
|
+
* (`LocalTunnelService` here, `CloudTunnelService` in plugin-elizacloud,
|
|
8
|
+
* the ngrok service, etc.) won the `serviceType="tunnel"` slot.
|
|
9
|
+
*/
|
|
10
|
+
export declare const tunnelStateProvider: Provider;
|
|
11
|
+
export default tunnelStateProvider;
|
|
12
|
+
//# sourceMappingURL=tunnel-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel-state.d.ts","sourceRoot":"","sources":["../../src/providers/tunnel-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG9C;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAgCjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { getTunnelService } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Surfaces the active tunnel's status into the model's state. Renders a
|
|
4
|
+
* one-line text summary and exposes the raw status object via `data`.
|
|
5
|
+
*
|
|
6
|
+
* Backend-agnostic — works with whichever tunnel implementation
|
|
7
|
+
* (`LocalTunnelService` here, `CloudTunnelService` in plugin-elizacloud,
|
|
8
|
+
* the ngrok service, etc.) won the `serviceType="tunnel"` slot.
|
|
9
|
+
*/
|
|
10
|
+
export const tunnelStateProvider = {
|
|
11
|
+
name: 'TUNNEL_STATE',
|
|
12
|
+
description: 'Current tunnel status: active flag, public URL, local port, provider, backend.',
|
|
13
|
+
descriptionCompressed: 'Tunnel: active/url/port/provider/backend',
|
|
14
|
+
contexts: ['devtools', 'system'],
|
|
15
|
+
relevanceKeywords: ['tunnel', 'tailscale', 'headscale', 'ngrok', 'serve', 'funnel', 'expose'],
|
|
16
|
+
position: 200,
|
|
17
|
+
get: async (runtime, _message) => {
|
|
18
|
+
const svc = getTunnelService(runtime);
|
|
19
|
+
if (!svc) {
|
|
20
|
+
return {
|
|
21
|
+
text: 'No tunnel service is registered.',
|
|
22
|
+
data: {
|
|
23
|
+
active: false,
|
|
24
|
+
available: false,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
const status = svc.getStatus();
|
|
29
|
+
const text = status.active
|
|
30
|
+
? `Tunnel ACTIVE — ${status.url ?? 'unknown URL'} (port ${status.port}, ${status.provider}${status.backend ? `/${status.backend}` : ''})`
|
|
31
|
+
: `Tunnel idle (${status.provider} ready).`;
|
|
32
|
+
return {
|
|
33
|
+
text,
|
|
34
|
+
data: {
|
|
35
|
+
available: true,
|
|
36
|
+
...status,
|
|
37
|
+
startedAt: status.startedAt ? status.startedAt.toISOString() : null,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
export default tunnelStateProvider;
|
|
43
|
+
//# sourceMappingURL=tunnel-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnel-state.js","sourceRoot":"","sources":["../../src/providers/tunnel-state.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAa;IAC3C,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,gFAAgF;IAC7F,qBAAqB,EAAE,0CAA0C;IACjE,QAAQ,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC;IAChC,iBAAiB,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC;IAC7F,QAAQ,EAAE,GAAG;IAEb,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;QAC/B,MAAM,GAAG,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO;gBACL,IAAI,EAAE,kCAAkC;gBACxC,IAAI,EAAE;oBACJ,MAAM,EAAE,KAAK;oBACb,SAAS,EAAE,KAAK;iBACjB;aACF,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM;YACxB,CAAC,CAAC,mBAAmB,MAAM,CAAC,GAAG,IAAI,aAAa,UAAU,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG;YACzI,CAAC,CAAC,gBAAgB,MAAM,CAAC,QAAQ,UAAU,CAAC;QAC9C,OAAO;YACL,IAAI;YACJ,IAAI,EAAE;gBACJ,SAAS,EAAE,IAAI;gBACf,GAAG,MAAM;gBACT,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI;aACpE;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type IAgentRuntime, Service } from '@elizaos/core';
|
|
2
|
+
import type { ITunnelService, TunnelStatus } from '../types';
|
|
3
|
+
export declare function checkTailscaleInstalled(): Promise<boolean>;
|
|
4
|
+
/**
|
|
5
|
+
* Tunnel service backed by the locally-installed `tailscale` CLI.
|
|
6
|
+
*
|
|
7
|
+
* The user is responsible for `tailscale up` (i.e. authenticating with
|
|
8
|
+
* Tailscale's coordination server, OR with a self-hosted headscale via
|
|
9
|
+
* `--login-server`). This service just calls `tailscale serve` / `tailscale
|
|
10
|
+
* funnel` to expose a port and reads `tailscale status --json` to learn the
|
|
11
|
+
* tailnet DNS name.
|
|
12
|
+
*
|
|
13
|
+
* Coexists with `@elizaos/plugin-elizacloud`'s cloud tunnel and
|
|
14
|
+
* `@elizaos/plugin-ngrok` — only the first one to register `serviceType="tunnel"`
|
|
15
|
+
* wins. This service registers itself only if the `tailscale` binary is on
|
|
16
|
+
* `PATH`, gating out machines that have no Tailscale install.
|
|
17
|
+
*/
|
|
18
|
+
export declare class LocalTunnelService extends Service implements ITunnelService {
|
|
19
|
+
static serviceType: string;
|
|
20
|
+
readonly capabilityDescription = "Tunnel via the locally-installed `tailscale` CLI (serve / funnel). User authenticates separately with `tailscale up`.";
|
|
21
|
+
private tunnelUrl;
|
|
22
|
+
private tunnelPort;
|
|
23
|
+
private startedAt;
|
|
24
|
+
private isShuttingDown;
|
|
25
|
+
private useFunnel;
|
|
26
|
+
static start(runtime: IAgentRuntime): Promise<Service>;
|
|
27
|
+
start(): Promise<void>;
|
|
28
|
+
stop(): Promise<void>;
|
|
29
|
+
startTunnel(port?: number): Promise<string | undefined>;
|
|
30
|
+
stopTunnel(): Promise<void>;
|
|
31
|
+
getUrl(): string | null;
|
|
32
|
+
isActive(): boolean;
|
|
33
|
+
getStatus(): TunnelStatus;
|
|
34
|
+
private fetchSelfDnsName;
|
|
35
|
+
private cleanup;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=LocalTunnelService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalTunnelService.d.ts","sourceRoot":"","sources":["../../src/services/LocalTunnelService.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,aAAa,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAGzE,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AA2C7D,wBAAgB,uBAAuB,IAAI,OAAO,CAAC,OAAO,CAAC,CAM1D;AAaD;;;;;;;;;;;;;GAaG;AACH,qBAAa,kBAAmB,SAAQ,OAAQ,YAAW,cAAc;IACvE,OAAgB,WAAW,SAAY;IACvC,QAAQ,CAAC,qBAAqB,2HAC4F;IAE1H,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,SAAS,CAAS;WAEJ,KAAK,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IAM/D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAUtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAwDvD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBjC,MAAM,IAAI,MAAM,GAAG,IAAI;IAIvB,QAAQ,IAAI,OAAO;IAInB,SAAS,IAAI,YAAY;YAWX,gBAAgB;IAgB9B,OAAO,CAAC,OAAO;CAMhB"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { elizaLogger, Service } from '@elizaos/core';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { validateTunnelConfig } from '../environment';
|
|
5
|
+
const tailscaleStatusPeerSchema = z.object({
|
|
6
|
+
DNSName: z.string().optional(),
|
|
7
|
+
Online: z.boolean().optional(),
|
|
8
|
+
});
|
|
9
|
+
const tailscaleStatusSchema = z.object({
|
|
10
|
+
Self: z
|
|
11
|
+
.object({
|
|
12
|
+
DNSName: z.string().optional(),
|
|
13
|
+
})
|
|
14
|
+
.optional(),
|
|
15
|
+
MagicDNSSuffix: z.string().optional(),
|
|
16
|
+
Peer: z.record(z.string(), tailscaleStatusPeerSchema).optional(),
|
|
17
|
+
});
|
|
18
|
+
function runCommand(cmd, args) {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
const child = spawn(cmd, args, { stdio: ['ignore', 'pipe', 'pipe'] });
|
|
21
|
+
const out = [];
|
|
22
|
+
const err = [];
|
|
23
|
+
child.stdout.on('data', (chunk) => out.push(chunk));
|
|
24
|
+
child.stderr.on('data', (chunk) => err.push(chunk));
|
|
25
|
+
child.on('error', reject);
|
|
26
|
+
child.on('exit', (code) => resolve({
|
|
27
|
+
code,
|
|
28
|
+
stdout: Buffer.concat(out).toString('utf8'),
|
|
29
|
+
stderr: Buffer.concat(err).toString('utf8'),
|
|
30
|
+
}));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
export function checkTailscaleInstalled() {
|
|
34
|
+
return new Promise((resolve) => {
|
|
35
|
+
const proc = spawn('which', ['tailscale']);
|
|
36
|
+
proc.on('exit', (code) => resolve(code === 0));
|
|
37
|
+
proc.on('error', () => resolve(false));
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function parseTailscaleStatus(stdout) {
|
|
41
|
+
let raw;
|
|
42
|
+
try {
|
|
43
|
+
raw = JSON.parse(stdout);
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const result = tailscaleStatusSchema.safeParse(raw);
|
|
49
|
+
return result.success ? result.data : null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Tunnel service backed by the locally-installed `tailscale` CLI.
|
|
53
|
+
*
|
|
54
|
+
* The user is responsible for `tailscale up` (i.e. authenticating with
|
|
55
|
+
* Tailscale's coordination server, OR with a self-hosted headscale via
|
|
56
|
+
* `--login-server`). This service just calls `tailscale serve` / `tailscale
|
|
57
|
+
* funnel` to expose a port and reads `tailscale status --json` to learn the
|
|
58
|
+
* tailnet DNS name.
|
|
59
|
+
*
|
|
60
|
+
* Coexists with `@elizaos/plugin-elizacloud`'s cloud tunnel and
|
|
61
|
+
* `@elizaos/plugin-ngrok` — only the first one to register `serviceType="tunnel"`
|
|
62
|
+
* wins. This service registers itself only if the `tailscale` binary is on
|
|
63
|
+
* `PATH`, gating out machines that have no Tailscale install.
|
|
64
|
+
*/
|
|
65
|
+
export class LocalTunnelService extends Service {
|
|
66
|
+
static serviceType = 'tunnel';
|
|
67
|
+
capabilityDescription = 'Tunnel via the locally-installed `tailscale` CLI (serve / funnel). User authenticates separately with `tailscale up`.';
|
|
68
|
+
tunnelUrl = null;
|
|
69
|
+
tunnelPort = null;
|
|
70
|
+
startedAt = null;
|
|
71
|
+
isShuttingDown = false;
|
|
72
|
+
useFunnel = false;
|
|
73
|
+
static async start(runtime) {
|
|
74
|
+
const service = new LocalTunnelService(runtime);
|
|
75
|
+
await service.start();
|
|
76
|
+
return service;
|
|
77
|
+
}
|
|
78
|
+
async start() {
|
|
79
|
+
elizaLogger.info('[LocalTunnelService] starting');
|
|
80
|
+
const installed = await checkTailscaleInstalled();
|
|
81
|
+
if (!installed) {
|
|
82
|
+
throw new Error('tailscale is not installed. Install from https://tailscale.com/download or run: brew install tailscale');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async stop() {
|
|
86
|
+
await this.stopTunnel();
|
|
87
|
+
}
|
|
88
|
+
async startTunnel(port) {
|
|
89
|
+
if (this.isActive()) {
|
|
90
|
+
elizaLogger.warn('[LocalTunnelService] tunnel already running');
|
|
91
|
+
return this.tunnelUrl ?? undefined;
|
|
92
|
+
}
|
|
93
|
+
if (port === undefined || port === null) {
|
|
94
|
+
elizaLogger.warn('[LocalTunnelService] startTunnel called without a port — service active but no tunnel started');
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
98
|
+
throw new Error('Invalid port number');
|
|
99
|
+
}
|
|
100
|
+
const config = await validateTunnelConfig(this.runtime);
|
|
101
|
+
this.useFunnel = config.TUNNEL_FUNNEL;
|
|
102
|
+
elizaLogger.info(`[LocalTunnelService] starting tunnel on port ${port} (funnel=${this.useFunnel})`);
|
|
103
|
+
if (this.useFunnel) {
|
|
104
|
+
const result = await runCommand('tailscale', ['funnel', String(port)]);
|
|
105
|
+
if (result.code !== 0) {
|
|
106
|
+
throw new Error(`tailscale funnel exited with code ${result.code}: ${result.stderr.trim()}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
const result = await runCommand('tailscale', [
|
|
111
|
+
'serve',
|
|
112
|
+
'--bg',
|
|
113
|
+
'--https=443',
|
|
114
|
+
`localhost:${port}`,
|
|
115
|
+
]);
|
|
116
|
+
if (result.code !== 0) {
|
|
117
|
+
throw new Error(`tailscale serve exited with code ${result.code}: ${result.stderr.trim()}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const dnsName = await this.fetchSelfDnsName();
|
|
121
|
+
if (!dnsName) {
|
|
122
|
+
throw new Error('tailscale serve started but no DNSName resolved from `tailscale status --json`');
|
|
123
|
+
}
|
|
124
|
+
this.tunnelUrl = `https://${dnsName}`;
|
|
125
|
+
this.tunnelPort = port;
|
|
126
|
+
this.startedAt = new Date();
|
|
127
|
+
elizaLogger.info(`[LocalTunnelService] tunnel started: ${this.tunnelUrl}`);
|
|
128
|
+
return this.tunnelUrl;
|
|
129
|
+
}
|
|
130
|
+
async stopTunnel() {
|
|
131
|
+
if (!this.isActive()) {
|
|
132
|
+
elizaLogger.warn('[LocalTunnelService] no active tunnel to stop');
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
this.isShuttingDown = true;
|
|
136
|
+
elizaLogger.info('[LocalTunnelService] stopping tunnel');
|
|
137
|
+
if (this.useFunnel) {
|
|
138
|
+
await runCommand('tailscale', ['funnel', 'reset']);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
await runCommand('tailscale', ['serve', 'reset']);
|
|
142
|
+
}
|
|
143
|
+
this.cleanup();
|
|
144
|
+
this.isShuttingDown = false;
|
|
145
|
+
elizaLogger.info('[LocalTunnelService] tunnel stopped');
|
|
146
|
+
}
|
|
147
|
+
getUrl() {
|
|
148
|
+
return this.tunnelUrl;
|
|
149
|
+
}
|
|
150
|
+
isActive() {
|
|
151
|
+
return this.tunnelUrl !== null && !this.isShuttingDown;
|
|
152
|
+
}
|
|
153
|
+
getStatus() {
|
|
154
|
+
return {
|
|
155
|
+
active: this.isActive(),
|
|
156
|
+
url: this.tunnelUrl,
|
|
157
|
+
port: this.tunnelPort,
|
|
158
|
+
startedAt: this.startedAt,
|
|
159
|
+
provider: 'tailscale',
|
|
160
|
+
backend: 'local-cli',
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
async fetchSelfDnsName() {
|
|
164
|
+
const result = await runCommand('tailscale', ['status', '--json']);
|
|
165
|
+
if (result.code !== 0) {
|
|
166
|
+
elizaLogger.error(`[LocalTunnelService] tailscale status failed: ${result.stderr.trim()}`);
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
const status = parseTailscaleStatus(result.stdout);
|
|
170
|
+
if (!status) {
|
|
171
|
+
elizaLogger.error('[LocalTunnelService] tailscale status returned malformed JSON');
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
const raw = status.Self?.DNSName;
|
|
175
|
+
if (!raw)
|
|
176
|
+
return null;
|
|
177
|
+
return raw.replace(/\.$/, '');
|
|
178
|
+
}
|
|
179
|
+
cleanup() {
|
|
180
|
+
this.tunnelUrl = null;
|
|
181
|
+
this.tunnelPort = null;
|
|
182
|
+
this.startedAt = null;
|
|
183
|
+
this.useFunnel = false;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=LocalTunnelService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalTunnelService.js","sourceRoot":"","sources":["../../src/services/LocalTunnelService.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tunnel-service contract shared across all elizaOS tunnel plugins.
|
|
3
|
+
*
|
|
4
|
+
* All tunnel plugins (`@elizaos/plugin-tunnel`, `@elizaos/plugin-elizacloud`'s
|
|
5
|
+
* cloud tunnel, `@elizaos/plugin-ngrok`) register under
|
|
6
|
+
* `serviceType = "tunnel"` so consumers stay backend-agnostic via
|
|
7
|
+
* `runtime.getService("tunnel")`. The runtime returns the FIRST registered
|
|
8
|
+
* service for a given type, so plugins coordinate via conditional
|
|
9
|
+
* registration: each plugin's `init` only registers if its credentials are
|
|
10
|
+
* present and no other tunnel service has already claimed the slot.
|
|
11
|
+
*/
|
|
12
|
+
import type { IAgentRuntime } from '@elizaos/core';
|
|
13
|
+
declare module '@elizaos/core' {
|
|
14
|
+
interface ServiceTypeRegistry {
|
|
15
|
+
TUNNEL: 'tunnel';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export type TunnelProvider = 'tailscale' | 'headscale' | 'ngrok';
|
|
19
|
+
export interface TunnelStatus {
|
|
20
|
+
active: boolean;
|
|
21
|
+
url: string | null;
|
|
22
|
+
port: number | null;
|
|
23
|
+
startedAt: Date | null;
|
|
24
|
+
provider: TunnelProvider;
|
|
25
|
+
/** Optional human label distinguishing backend variants (e.g. "local-cli", "eliza-cloud-headscale"). */
|
|
26
|
+
backend?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface ITunnelService {
|
|
29
|
+
startTunnel(port?: number): Promise<string | undefined>;
|
|
30
|
+
stopTunnel(): Promise<void>;
|
|
31
|
+
getUrl(): string | null;
|
|
32
|
+
isActive(): boolean;
|
|
33
|
+
getStatus(): TunnelStatus;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Backend-agnostic accessor. Returns the first registered service that
|
|
37
|
+
* implements the tunnel contract; returns null if nothing is registered or
|
|
38
|
+
* the registered service doesn't satisfy the shape (defensive guard against
|
|
39
|
+
* an unrelated service registering under "tunnel").
|
|
40
|
+
*/
|
|
41
|
+
export declare function getTunnelService(runtime: IAgentRuntime): ITunnelService | null;
|
|
42
|
+
/**
|
|
43
|
+
* True iff no tunnel service has claimed `serviceType="tunnel"` yet.
|
|
44
|
+
* Used by tunnel plugins' `init` hooks to coordinate "first active wins".
|
|
45
|
+
*/
|
|
46
|
+
export declare function tunnelSlotIsFree(runtime: IAgentRuntime): boolean;
|
|
47
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAW,MAAM,eAAe,CAAC;AAE5D,OAAO,QAAQ,eAAe,CAAC;IAC7B,UAAU,mBAAmB;QAC3B,MAAM,EAAE,QAAQ,CAAC;KAClB;CACF;AAED,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,WAAW,GAAG,OAAO,CAAC;AAEjE,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,cAAc,CAAC;IACzB,wGAAwG;IACxG,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACxD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,IAAI,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,IAAI,OAAO,CAAC;IACpB,SAAS,IAAI,YAAY,CAAC;CAC3B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,cAAc,GAAG,IAAI,CAO9E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAEhE"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tunnel-service contract shared across all elizaOS tunnel plugins.
|
|
3
|
+
*
|
|
4
|
+
* All tunnel plugins (`@elizaos/plugin-tunnel`, `@elizaos/plugin-elizacloud`'s
|
|
5
|
+
* cloud tunnel, `@elizaos/plugin-ngrok`) register under
|
|
6
|
+
* `serviceType = "tunnel"` so consumers stay backend-agnostic via
|
|
7
|
+
* `runtime.getService("tunnel")`. The runtime returns the FIRST registered
|
|
8
|
+
* service for a given type, so plugins coordinate via conditional
|
|
9
|
+
* registration: each plugin's `init` only registers if its credentials are
|
|
10
|
+
* present and no other tunnel service has already claimed the slot.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Backend-agnostic accessor. Returns the first registered service that
|
|
14
|
+
* implements the tunnel contract; returns null if nothing is registered or
|
|
15
|
+
* the registered service doesn't satisfy the shape (defensive guard against
|
|
16
|
+
* an unrelated service registering under "tunnel").
|
|
17
|
+
*/
|
|
18
|
+
export function getTunnelService(runtime) {
|
|
19
|
+
const service = runtime.getService('tunnel');
|
|
20
|
+
if (!service)
|
|
21
|
+
return null;
|
|
22
|
+
if (typeof service.startTunnel !== 'function') {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
return service;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* True iff no tunnel service has claimed `serviceType="tunnel"` yet.
|
|
29
|
+
* Used by tunnel plugins' `init` hooks to coordinate "first active wins".
|
|
30
|
+
*/
|
|
31
|
+
export function tunnelSlotIsFree(runtime) {
|
|
32
|
+
return runtime.getService('tunnel') === null;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA8BH;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAsB;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC7C,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,OAAQ,OAAmC,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;QAC3E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,OAAmC,CAAC;AAC7C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAsB;IACrD,OAAO,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC;AAC/C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elizaos/plugin-tunnel",
|
|
3
|
-
"version": "2.0.3-beta.
|
|
3
|
+
"version": "2.0.3-beta.7",
|
|
4
4
|
"description": "Tunnel plugin for elizaOS — local Tailscale CLI backend (serve/funnel). Pair with @elizaos/plugin-elizacloud for the hosted headscale backend.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"networking"
|
|
55
55
|
],
|
|
56
56
|
"peerDependencies": {
|
|
57
|
-
"@elizaos/core": "2.0.3-beta.
|
|
57
|
+
"@elizaos/core": "2.0.3-beta.7"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@elizaos/core": "2.0.3-beta.
|
|
60
|
+
"@elizaos/core": "2.0.3-beta.7",
|
|
61
61
|
"zod": "^4.4.2"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
@@ -73,5 +73,5 @@
|
|
|
73
73
|
"pluginType": "elizaos:plugin:1.0.0",
|
|
74
74
|
"pluginParameters": {}
|
|
75
75
|
},
|
|
76
|
-
"gitHead": "
|
|
76
|
+
"gitHead": "61094f10458d11055c75b3dd0bae374e3f66bac5"
|
|
77
77
|
}
|