@sleep2agi/agent-network 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/README.md +152 -0
- package/dist/bin/cli.js +234 -0
- package/dist/client.d.ts +78 -0
- package/dist/src/client.js +2 -0
- package/package.json +56 -0
- package/src/server.ts +28 -0
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @sleep2agi/commhub-sdk
|
|
3
|
+
*
|
|
4
|
+
* CommHub 通信 SDK — 一个文件,SSE 长连接 + 自动重连 + 心跳。
|
|
5
|
+
* 支持 Node.js 18+ 和 Bun。
|
|
6
|
+
*/
|
|
7
|
+
import { EventEmitter } from "events";
|
|
8
|
+
export interface CommHubOptions {
|
|
9
|
+
/** CommHub Server URL, e.g. "http://YOUR_COMMHUB_IP:9200" */
|
|
10
|
+
url: string;
|
|
11
|
+
/** Session alias, e.g. "SDK马" */
|
|
12
|
+
alias: string;
|
|
13
|
+
/** Auth token (optional) */
|
|
14
|
+
token?: string;
|
|
15
|
+
/** Agent type for registration (default: "sdk") */
|
|
16
|
+
agent?: string;
|
|
17
|
+
/** Heartbeat interval in ms (default: 180000 = 3 min) */
|
|
18
|
+
heartbeatInterval?: number;
|
|
19
|
+
/** SSE reconnect base delay in ms (default: 3000) */
|
|
20
|
+
reconnectDelay?: number;
|
|
21
|
+
/** Auto-connect on creation (default: true) */
|
|
22
|
+
autoConnect?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface InboxMessage {
|
|
25
|
+
id: string;
|
|
26
|
+
content: string;
|
|
27
|
+
from_session: string;
|
|
28
|
+
priority: string;
|
|
29
|
+
created_at: string;
|
|
30
|
+
}
|
|
31
|
+
export interface CommHubEvents {
|
|
32
|
+
task: (msg: InboxMessage) => void;
|
|
33
|
+
message: (msg: InboxMessage) => void;
|
|
34
|
+
connected: () => void;
|
|
35
|
+
disconnected: () => void;
|
|
36
|
+
error: (err: Error) => void;
|
|
37
|
+
}
|
|
38
|
+
export declare class CommHub extends EventEmitter {
|
|
39
|
+
private url;
|
|
40
|
+
private alias;
|
|
41
|
+
private token?;
|
|
42
|
+
private agent;
|
|
43
|
+
private resumeId;
|
|
44
|
+
private heartbeatInterval;
|
|
45
|
+
private reconnectDelay;
|
|
46
|
+
private heartbeatTimer?;
|
|
47
|
+
private sseAbort?;
|
|
48
|
+
private running;
|
|
49
|
+
constructor(opts: CommHubOptions);
|
|
50
|
+
private log;
|
|
51
|
+
private call;
|
|
52
|
+
/** Connect to CommHub: register + start SSE + heartbeat */
|
|
53
|
+
connect(): Promise<void>;
|
|
54
|
+
/** Disconnect: stop SSE + heartbeat, report offline */
|
|
55
|
+
disconnect(): Promise<void>;
|
|
56
|
+
/** Send a task to another session */
|
|
57
|
+
send(targetAlias: string, content: string, priority?: "high" | "normal" | "low"): Promise<any>;
|
|
58
|
+
/** Send a message (no task lifecycle) */
|
|
59
|
+
message(targetAlias: string, content: string): Promise<any>;
|
|
60
|
+
/** Reply to a task (update status) */
|
|
61
|
+
reply(taskId: string, text: string, status?: "completed" | "blocked" | "error" | "in_progress"): Promise<any>;
|
|
62
|
+
/** Update session status */
|
|
63
|
+
status(state: string, extra?: {
|
|
64
|
+
task?: string;
|
|
65
|
+
progress?: number;
|
|
66
|
+
}): Promise<any>;
|
|
67
|
+
/** Get all session statuses */
|
|
68
|
+
getAllStatus(): Promise<any>;
|
|
69
|
+
/** Broadcast to all sessions */
|
|
70
|
+
broadcast(content: string, filter?: {
|
|
71
|
+
server?: string;
|
|
72
|
+
status?: string;
|
|
73
|
+
}): Promise<any>;
|
|
74
|
+
private connectSSE;
|
|
75
|
+
private processInbox;
|
|
76
|
+
private sleep;
|
|
77
|
+
}
|
|
78
|
+
export default CommHub;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{createRequire as I}from"node:module";var X=Object.create;var{getPrototypeOf:Y,defineProperty:M,getOwnPropertyNames:Z}=Object;var _=Object.prototype.hasOwnProperty;function $(j){return this[j]}var J,K,H=(j,q,w)=>{var z=j!=null&&typeof j==="object";if(z){var B=q?J??=new WeakMap:K??=new WeakMap,D=B.get(j);if(D)return D}w=j!=null?X(Y(j)):{};let G=q||!j||!j.__esModule?M(w,"default",{value:j,enumerable:!0}):w;for(let F of Z(j))if(!_.call(G,F))M(G,F,{get:$.bind(j,F),enumerable:!0});if(z)B.set(j,G);return G};var b=(j,q)=>()=>(q||j((q={exports:{}}).exports,q),q.exports);var N=(j)=>j;function O(j,q){this[j]=N.bind(null,q)}var S=(j,q)=>{for(var w in q)M(j,w,{get:q[w],enumerable:!0,configurable:!0,set:O.bind(q,w)})};var U=(j,q)=>()=>(j&&(q=j(j=0)),q);var A=I(import.meta.url);var C={};S(C,{default:()=>E,CommHub:()=>P});import{EventEmitter as k}from"events";import{hostname as T}from"os";var P,E;var h=U(()=>{P=class P extends k{url;alias;token;agent;resumeId;heartbeatInterval;reconnectDelay;heartbeatTimer;sseAbort;running=!1;constructor(j){super();if(this.url=j.url.replace(/\/$/,""),this.alias=j.alias,this.token=j.token,this.agent=j.agent||"sdk",this.resumeId=`sdk-${j.alias}-${Date.now().toString(36)}`,this.heartbeatInterval=j.heartbeatInterval??180000,this.reconnectDelay=j.reconnectDelay??3000,j.autoConnect!==!1)this.connect()}log(j){console.log(`[${new Date().toTimeString().slice(0,8)}] [commhub:${this.alias}] ${j}`)}async call(j,q){let w={"Content-Type":"application/json"};if(this.token)w.Authorization=`Bearer ${this.token}`;let B=await(await fetch(`${this.url}/mcp`,{method:"POST",headers:w,body:JSON.stringify({jsonrpc:"2.0",id:Date.now(),method:"tools/call",params:{name:j,arguments:q}})})).json(),D=B?.result?.content?.[0]?.text;return D?JSON.parse(D):B}async connect(){if(this.running)return;this.running=!0,await this.status("idle"),this.log("registered"),this.heartbeatTimer=setInterval(()=>{this.status("idle").catch((j)=>this.log(`heartbeat failed: ${j.message}`))},this.heartbeatInterval),this.connectSSE()}async disconnect(){if(this.running=!1,this.sseAbort?.abort(),this.heartbeatTimer)clearInterval(this.heartbeatTimer);await this.status("offline").catch(()=>{}),this.log("disconnected")}async send(j,q,w="normal"){return this.call("send_task",{alias:j,task:q,priority:w,from_session:this.alias})}async message(j,q){return this.call("send_message",{alias:j,message:q,from_session:this.alias})}async reply(j,q,w="completed"){return this.call("reply",{task_id:j,text:q,status:w})}async status(j,q){return this.call("report_status",{resume_id:this.resumeId,alias:this.alias,status:j,server:T(),hostname:T(),agent:this.agent,project_dir:process.cwd(),...q})}async getAllStatus(){return this.call("get_all_status",{})}async broadcast(j,q){return this.call("broadcast",{message:j,filter_server:q?.server,filter_status:q?.status})}async connectSSE(){let j=encodeURIComponent(this.alias),q=`${this.url}/events/${j}`,w=this.reconnectDelay;while(this.running){try{this.sseAbort=new AbortController;let z={Accept:"text/event-stream"};if(this.token)z.Authorization=`Bearer ${this.token}`;let B=await fetch(q,{headers:z,signal:this.sseAbort.signal});if(!B.ok||!B.body){this.log(`SSE failed: ${B.status}`),await this.sleep(w),w=Math.min(w*1.5,60000);continue}w=this.reconnectDelay;let D=B.body.getReader(),G=new TextDecoder,F="";while(this.running){let{done:V,value:W}=await D.read();if(V)break;F+=G.decode(W,{stream:!0});let Q=F.split(`
|
|
2
|
+
`);F=Q.pop()||"";for(let R of Q){if(!R.startsWith("data: "))continue;try{let L=JSON.parse(R.slice(6));if(L.type==="connected"){this.log("SSE connected"),this.emit("connected");continue}if(L.type==="new_task"||L.type==="new_message"||L.type==="broadcast")await this.processInbox()}catch{}}}}catch(z){if(z.name==="AbortError")break;this.emit("error",z),this.log(`SSE error: ${z.message}`)}if(this.running)this.emit("disconnected"),this.log(`SSE reconnecting in ${w/1000}s...`),await this.sleep(w),w=Math.min(w*1.5,60000)}}async processInbox(){try{let q=(await this.call("get_inbox",{alias:this.alias,limit:10}))?.messages||[];for(let w of q)await this.call("ack_inbox",{alias:this.alias,message_id:w.id}),this.log(`← ${w.from_session}: ${w.content.slice(0,60)}`),this.emit("task",w),this.emit("message",w)}catch(j){this.log(`inbox error: ${j.message}`)}}sleep(j){return new Promise((q)=>setTimeout(q,j))}};E=P});h();export{E as default,P as CommHub};
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sleep2agi/agent-network",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "AI Agent Network — Server + Client + Setup in one package. SSE real-time communication for multi-agent orchestration.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/src/client.js",
|
|
7
|
+
"types": "dist/client.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/src/client.js",
|
|
11
|
+
"types": "./dist/client.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./server": {
|
|
14
|
+
"import": "./src/server.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"bin": {
|
|
18
|
+
"agent-network": "dist/bin/cli.js"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"src/server.ts"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "bun build src/client.ts bin/cli.ts --outdir dist --target node --minify && tsc --emitDeclarationOnly --declaration --outDir dist",
|
|
26
|
+
"prepublishOnly": "npm run build"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"agent",
|
|
30
|
+
"network",
|
|
31
|
+
"ai",
|
|
32
|
+
"mcp",
|
|
33
|
+
"sse",
|
|
34
|
+
"claude",
|
|
35
|
+
"openai",
|
|
36
|
+
"minimax",
|
|
37
|
+
"orchestration",
|
|
38
|
+
"communication",
|
|
39
|
+
"hub",
|
|
40
|
+
"multi-agent"
|
|
41
|
+
],
|
|
42
|
+
"author": "sleep2agi",
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "https://github.com/sleep2agi/agent-comm-hub",
|
|
47
|
+
"directory": "agent-network"
|
|
48
|
+
},
|
|
49
|
+
"engines": {
|
|
50
|
+
"bun": ">=1.2.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^25.0.0",
|
|
54
|
+
"typescript": "^5.0.0"
|
|
55
|
+
}
|
|
56
|
+
}
|
package/src/server.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CommHub Server — AI Agent communication hub
|
|
3
|
+
*
|
|
4
|
+
* Reexports the server startup. The actual server code lives in
|
|
5
|
+
* the commhub-server package (server/ directory). This module
|
|
6
|
+
* provides a programmatic entry point.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export interface ServerOptions {
|
|
10
|
+
port?: number;
|
|
11
|
+
token?: string;
|
|
12
|
+
db?: string;
|
|
13
|
+
corsOrigins?: string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Start CommHub server programmatically.
|
|
18
|
+
* Sets environment variables and imports the server module.
|
|
19
|
+
*/
|
|
20
|
+
export async function startServer(opts: ServerOptions = {}) {
|
|
21
|
+
if (opts.port) process.env.PORT = String(opts.port);
|
|
22
|
+
if (opts.token) process.env.COMMHUB_AUTH_TOKEN = opts.token;
|
|
23
|
+
if (opts.db) process.env.COMMHUB_DB = opts.db;
|
|
24
|
+
if (opts.corsOrigins) process.env.COMMHUB_CORS_ORIGINS = opts.corsOrigins.join(",");
|
|
25
|
+
|
|
26
|
+
// Dynamic import to avoid loading server code when only using client
|
|
27
|
+
await import("../../server/src/index.js");
|
|
28
|
+
}
|