network-ai 5.13.4 → 5.14.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/INTEGRATION_GUIDE.md +6 -3
- package/QUICKSTART.md +9 -4
- package/README.md +64 -14
- package/SKILL.md +1 -1
- package/bin/cli.ts +73 -0
- package/bin/mcp-server.ts +15 -1
- package/dist/adapters/claude-agent-sdk-adapter.d.ts +100 -0
- package/dist/adapters/claude-agent-sdk-adapter.d.ts.map +1 -0
- package/dist/adapters/claude-agent-sdk-adapter.js +204 -0
- package/dist/adapters/claude-agent-sdk-adapter.js.map +1 -0
- package/dist/adapters/gemini-adapter.d.ts +124 -0
- package/dist/adapters/gemini-adapter.d.ts.map +1 -0
- package/dist/adapters/gemini-adapter.js +239 -0
- package/dist/adapters/gemini-adapter.js.map +1 -0
- package/dist/adapters/index.d.ts +6 -0
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +10 -1
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/openai-responses-adapter.d.ts +119 -0
- package/dist/adapters/openai-responses-adapter.d.ts.map +1 -0
- package/dist/adapters/openai-responses-adapter.js +235 -0
- package/dist/adapters/openai-responses-adapter.js.map +1 -0
- package/dist/bin/cli.js +72 -0
- package/dist/bin/cli.js.map +1 -1
- package/dist/bin/mcp-server.js +14 -1
- package/dist/bin/mcp-server.js.map +1 -1
- package/dist/esm/adapters/claude-agent-sdk-adapter.js +204 -0
- package/dist/esm/adapters/claude-agent-sdk-adapter.js.map +1 -0
- package/dist/esm/adapters/gemini-adapter.js +239 -0
- package/dist/esm/adapters/gemini-adapter.js.map +1 -0
- package/dist/esm/adapters/index.js +10 -1
- package/dist/esm/adapters/index.js.map +1 -1
- package/dist/esm/adapters/openai-responses-adapter.js +235 -0
- package/dist/esm/adapters/openai-responses-adapter.js.map +1 -0
- package/dist/esm/index.js +13 -5
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/a2a-server.js +293 -0
- package/dist/esm/lib/a2a-server.js.map +1 -0
- package/dist/esm/lib/claude-hooks.js +307 -0
- package/dist/esm/lib/claude-hooks.js.map +1 -0
- package/dist/esm/lib/mcp-elicitation.js +198 -0
- package/dist/esm/lib/mcp-elicitation.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -5
- package/dist/index.js.map +1 -1
- package/dist/lib/a2a-server.d.ts +120 -0
- package/dist/lib/a2a-server.d.ts.map +1 -0
- package/dist/lib/a2a-server.js +293 -0
- package/dist/lib/a2a-server.js.map +1 -0
- package/dist/lib/claude-hooks.d.ts +150 -0
- package/dist/lib/claude-hooks.d.ts.map +1 -0
- package/dist/lib/claude-hooks.js +307 -0
- package/dist/lib/claude-hooks.js.map +1 -0
- package/dist/lib/mcp-elicitation.d.ts +116 -0
- package/dist/lib/mcp-elicitation.d.ts.map +1 -0
- package/dist/lib/mcp-elicitation.js +198 -0
- package/dist/lib/mcp-elicitation.js.map +1 -0
- package/package.json +2 -2
- package/scripts/clawhub-publish.js +14 -1
- package/socket.json +1 -1
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A2A Server — expose Network-AI as a Google A2A (Agent2Agent) agent.
|
|
3
|
+
*
|
|
4
|
+
* The `A2AAdapter` (adapters/a2a-adapter.ts) lets this orchestrator *call*
|
|
5
|
+
* remote A2A agents. This module is the other direction: `A2AServer` serves
|
|
6
|
+
* an Agent Card at `/.well-known/agent.json` and accepts `tasks/send`
|
|
7
|
+
* JSON-RPC envelopes, so any A2A-speaking framework (Google ADK, Gemini
|
|
8
|
+
* agents, LangGraph A2A clients, …) can discover this orchestrator and hand
|
|
9
|
+
* it tasks.
|
|
10
|
+
*
|
|
11
|
+
* Incoming task text is delegated to a pluggable executor — typically a
|
|
12
|
+
* closure over `AdapterRegistry.executeAgent()` or
|
|
13
|
+
* `SwarmOrchestrator.delegateTask()`.
|
|
14
|
+
*
|
|
15
|
+
* Security posture mirrors `ApprovalInbox`:
|
|
16
|
+
* - binds to 127.0.0.1 by default;
|
|
17
|
+
* - optional Bearer `secret` gates the task routes (the Agent Card remains
|
|
18
|
+
* public — it is the A2A discovery document);
|
|
19
|
+
* - request bodies are size-capped; unknown methods are rejected.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const server = new A2AServer({
|
|
24
|
+
* name: 'Network-AI Orchestrator',
|
|
25
|
+
* description: 'Multi-agent swarm coordinator',
|
|
26
|
+
* secret: process.env.A2A_SECRET,
|
|
27
|
+
* executor: async (text) => {
|
|
28
|
+
* const result = await registry.executeAgent('custom:solver', {
|
|
29
|
+
* action: 'solve', params: { text },
|
|
30
|
+
* }, { agentId: 'a2a-server', taskId: 'a2a' });
|
|
31
|
+
* return { text: JSON.stringify(result.data) };
|
|
32
|
+
* },
|
|
33
|
+
* });
|
|
34
|
+
* server.startServer(4310);
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @module A2AServer
|
|
38
|
+
* @version 1.0.0
|
|
39
|
+
*/
|
|
40
|
+
import { type IncomingMessage, type Server, type ServerResponse } from 'http';
|
|
41
|
+
/** Task lifecycle states (A2A spec §4) */
|
|
42
|
+
export type A2AServerTaskState = 'submitted' | 'working' | 'completed' | 'canceled' | 'failed';
|
|
43
|
+
/** Executor invoked for every incoming `tasks/send` */
|
|
44
|
+
export type A2ATaskExecutor = (text: string, metadata: Record<string, unknown> | undefined) => Promise<{
|
|
45
|
+
text?: string;
|
|
46
|
+
data?: unknown;
|
|
47
|
+
}>;
|
|
48
|
+
/** A stored task record */
|
|
49
|
+
export interface A2AServerTask {
|
|
50
|
+
/** Task id (client-supplied or generated) */
|
|
51
|
+
id: string;
|
|
52
|
+
/** Current lifecycle state */
|
|
53
|
+
state: A2AServerTaskState;
|
|
54
|
+
/** The incoming message text */
|
|
55
|
+
input: string;
|
|
56
|
+
/** Output artifact text (present when completed) */
|
|
57
|
+
output?: string;
|
|
58
|
+
/** Failure/cancel message */
|
|
59
|
+
message?: string;
|
|
60
|
+
/** Creation timestamp (epoch ms) */
|
|
61
|
+
createdAt: number;
|
|
62
|
+
/** Resolution timestamp (epoch ms) */
|
|
63
|
+
resolvedAt?: number;
|
|
64
|
+
}
|
|
65
|
+
/** Options for the A2AServer */
|
|
66
|
+
export interface A2AServerOptions {
|
|
67
|
+
/** Agent name shown on the Agent Card */
|
|
68
|
+
name: string;
|
|
69
|
+
/** Agent description shown on the Agent Card */
|
|
70
|
+
description?: string;
|
|
71
|
+
/** Agent version shown on the Agent Card (default: '1.0.0') */
|
|
72
|
+
version?: string;
|
|
73
|
+
/** Public URL of this agent (advertised on the card) */
|
|
74
|
+
url?: string;
|
|
75
|
+
/**
|
|
76
|
+
* Bearer token required on the task routes when set. The Agent Card at
|
|
77
|
+
* /.well-known/agent.json stays public — it is the discovery document.
|
|
78
|
+
*/
|
|
79
|
+
secret?: string;
|
|
80
|
+
/** Executor that fulfils incoming tasks (required) */
|
|
81
|
+
executor: A2ATaskExecutor;
|
|
82
|
+
/** Maximum stored task records (default: 1000, oldest evicted first) */
|
|
83
|
+
maxHistory?: number;
|
|
84
|
+
/** Maximum request body size in bytes (default: 1 MiB) */
|
|
85
|
+
maxBodyBytes?: number;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Minimal, dependency-free A2A protocol server: Agent Card discovery plus
|
|
89
|
+
* `tasks/send`, `tasks/get`, and `tasks/cancel` over JSON-RPC 2.0.
|
|
90
|
+
*/
|
|
91
|
+
export declare class A2AServer {
|
|
92
|
+
private readonly options;
|
|
93
|
+
private readonly tasks;
|
|
94
|
+
constructor(options: A2AServerOptions);
|
|
95
|
+
/** Build the Agent Card served at /.well-known/agent.json */
|
|
96
|
+
agentCard(): Record<string, unknown>;
|
|
97
|
+
/** Get a stored task by id */
|
|
98
|
+
getTask(id: string): A2AServerTask | undefined;
|
|
99
|
+
/** Number of stored task records */
|
|
100
|
+
get taskCount(): number;
|
|
101
|
+
/**
|
|
102
|
+
* HTTP handler — mount on any node http server.
|
|
103
|
+
* Routes: GET /.well-known/agent.json, POST /tasks.
|
|
104
|
+
*/
|
|
105
|
+
httpHandler(): (req: IncomingMessage, res: ServerResponse) => void;
|
|
106
|
+
/**
|
|
107
|
+
* Convenience: create and start an http.Server with the handler mounted.
|
|
108
|
+
* Binds to 127.0.0.1 by default — expose deliberately, not accidentally.
|
|
109
|
+
*/
|
|
110
|
+
startServer(port: number, hostname?: string): Server;
|
|
111
|
+
private route;
|
|
112
|
+
private handleSend;
|
|
113
|
+
private handleGet;
|
|
114
|
+
private handleCancel;
|
|
115
|
+
private store;
|
|
116
|
+
private readBody;
|
|
117
|
+
private json;
|
|
118
|
+
private rpcError;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=a2a-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a2a-server.d.ts","sourceRoot":"","sources":["../../lib/a2a-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EAAgB,KAAK,eAAe,EAAE,KAAK,MAAM,EAAE,KAAK,cAAc,EAAE,MAAM,MAAM,CAAC;AAO5F,0CAA0C;AAC1C,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE/F,uDAAuD;AACvD,MAAM,MAAM,eAAe,GAAG,CAC5B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,KAC1C,OAAO,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEhD,2BAA2B;AAC3B,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,EAAE,EAAE,MAAM,CAAC;IACX,8BAA8B;IAC9B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,gCAAgC;AAChC,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,QAAQ,EAAE,eAAe,CAAC;IAC1B,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAkBD;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CACqD;IAC7E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;gBAE9C,OAAO,EAAE,gBAAgB;IAerC,6DAA6D;IAC7D,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAepC,8BAA8B;IAC9B,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI9C,oCAAoC;IACpC,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED;;;OAGG;IACH,WAAW,IAAI,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,IAAI;IAMlE;;;OAGG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAc,GAAG,MAAM;YAU3C,KAAK;YA4DL,UAAU;IA4DxB,OAAO,CAAC,SAAS;IAoBjB,OAAO,CAAC,YAAY;IAsBpB,OAAO,CAAC,KAAK;IAQb,OAAO,CAAC,QAAQ;IAkBhB,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,QAAQ;CAGjB"}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* A2A Server — expose Network-AI as a Google A2A (Agent2Agent) agent.
|
|
4
|
+
*
|
|
5
|
+
* The `A2AAdapter` (adapters/a2a-adapter.ts) lets this orchestrator *call*
|
|
6
|
+
* remote A2A agents. This module is the other direction: `A2AServer` serves
|
|
7
|
+
* an Agent Card at `/.well-known/agent.json` and accepts `tasks/send`
|
|
8
|
+
* JSON-RPC envelopes, so any A2A-speaking framework (Google ADK, Gemini
|
|
9
|
+
* agents, LangGraph A2A clients, …) can discover this orchestrator and hand
|
|
10
|
+
* it tasks.
|
|
11
|
+
*
|
|
12
|
+
* Incoming task text is delegated to a pluggable executor — typically a
|
|
13
|
+
* closure over `AdapterRegistry.executeAgent()` or
|
|
14
|
+
* `SwarmOrchestrator.delegateTask()`.
|
|
15
|
+
*
|
|
16
|
+
* Security posture mirrors `ApprovalInbox`:
|
|
17
|
+
* - binds to 127.0.0.1 by default;
|
|
18
|
+
* - optional Bearer `secret` gates the task routes (the Agent Card remains
|
|
19
|
+
* public — it is the A2A discovery document);
|
|
20
|
+
* - request bodies are size-capped; unknown methods are rejected.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const server = new A2AServer({
|
|
25
|
+
* name: 'Network-AI Orchestrator',
|
|
26
|
+
* description: 'Multi-agent swarm coordinator',
|
|
27
|
+
* secret: process.env.A2A_SECRET,
|
|
28
|
+
* executor: async (text) => {
|
|
29
|
+
* const result = await registry.executeAgent('custom:solver', {
|
|
30
|
+
* action: 'solve', params: { text },
|
|
31
|
+
* }, { agentId: 'a2a-server', taskId: 'a2a' });
|
|
32
|
+
* return { text: JSON.stringify(result.data) };
|
|
33
|
+
* },
|
|
34
|
+
* });
|
|
35
|
+
* server.startServer(4310);
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @module A2AServer
|
|
39
|
+
* @version 1.0.0
|
|
40
|
+
*/
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.A2AServer = void 0;
|
|
43
|
+
const http_1 = require("http");
|
|
44
|
+
const crypto_1 = require("crypto");
|
|
45
|
+
// ============================================================================
|
|
46
|
+
// A2A SERVER
|
|
47
|
+
// ============================================================================
|
|
48
|
+
/**
|
|
49
|
+
* Minimal, dependency-free A2A protocol server: Agent Card discovery plus
|
|
50
|
+
* `tasks/send`, `tasks/get`, and `tasks/cancel` over JSON-RPC 2.0.
|
|
51
|
+
*/
|
|
52
|
+
class A2AServer {
|
|
53
|
+
options;
|
|
54
|
+
tasks = new Map();
|
|
55
|
+
constructor(options) {
|
|
56
|
+
if (!options || typeof options.name !== 'string' || options.name.trim() === '') {
|
|
57
|
+
throw new Error('A2AServer: options.name is required');
|
|
58
|
+
}
|
|
59
|
+
if (typeof options.executor !== 'function') {
|
|
60
|
+
throw new Error('A2AServer: options.executor is required');
|
|
61
|
+
}
|
|
62
|
+
this.options = {
|
|
63
|
+
...options,
|
|
64
|
+
version: options.version ?? '1.0.0',
|
|
65
|
+
maxHistory: options.maxHistory ?? 1000,
|
|
66
|
+
maxBodyBytes: options.maxBodyBytes ?? 1024 * 1024,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Build the Agent Card served at /.well-known/agent.json */
|
|
70
|
+
agentCard() {
|
|
71
|
+
return {
|
|
72
|
+
name: this.options.name,
|
|
73
|
+
description: this.options.description ?? 'Network-AI multi-agent orchestrator (A2A server mode)',
|
|
74
|
+
version: this.options.version,
|
|
75
|
+
capabilities: {
|
|
76
|
+
streaming: false,
|
|
77
|
+
pushNotifications: false,
|
|
78
|
+
stateTransitionHistory: false,
|
|
79
|
+
},
|
|
80
|
+
...(this.options.url ? { url: this.options.url, taskEndpoint: `${this.options.url.replace(/\/+$/, '')}/tasks` } : { taskEndpoint: '/tasks' }),
|
|
81
|
+
authentication: this.options.secret ? { schemes: ['bearer'] } : { schemes: [] },
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/** Get a stored task by id */
|
|
85
|
+
getTask(id) {
|
|
86
|
+
return this.tasks.get(id);
|
|
87
|
+
}
|
|
88
|
+
/** Number of stored task records */
|
|
89
|
+
get taskCount() {
|
|
90
|
+
return this.tasks.size;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* HTTP handler — mount on any node http server.
|
|
94
|
+
* Routes: GET /.well-known/agent.json, POST /tasks.
|
|
95
|
+
*/
|
|
96
|
+
httpHandler() {
|
|
97
|
+
return (req, res) => {
|
|
98
|
+
void this.route(req, res);
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Convenience: create and start an http.Server with the handler mounted.
|
|
103
|
+
* Binds to 127.0.0.1 by default — expose deliberately, not accidentally.
|
|
104
|
+
*/
|
|
105
|
+
startServer(port, hostname = '127.0.0.1') {
|
|
106
|
+
const server = (0, http_1.createServer)(this.httpHandler());
|
|
107
|
+
server.listen(port, hostname);
|
|
108
|
+
return server;
|
|
109
|
+
}
|
|
110
|
+
// --------------------------------------------------------------------------
|
|
111
|
+
// Routing
|
|
112
|
+
// --------------------------------------------------------------------------
|
|
113
|
+
async route(req, res) {
|
|
114
|
+
const url = (req.url ?? '/').split('?')[0];
|
|
115
|
+
// Agent Card — public discovery document
|
|
116
|
+
if (req.method === 'GET' && url === '/.well-known/agent.json') {
|
|
117
|
+
this.json(res, 200, this.agentCard());
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (req.method === 'POST' && (url === '/tasks' || url === '/')) {
|
|
121
|
+
// Auth gate (fail closed when a secret is configured)
|
|
122
|
+
if (this.options.secret) {
|
|
123
|
+
const header = req.headers['authorization'] ?? '';
|
|
124
|
+
const ok = typeof header === 'string' && header === `Bearer ${this.options.secret}`;
|
|
125
|
+
if (!ok) {
|
|
126
|
+
this.json(res, 401, { error: 'unauthorized' });
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
let body;
|
|
131
|
+
try {
|
|
132
|
+
body = await this.readBody(req);
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
this.json(res, 413, { error: err instanceof Error ? err.message : 'body too large' });
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
let rpc;
|
|
139
|
+
try {
|
|
140
|
+
rpc = JSON.parse(body);
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
this.rpcError(res, null, -32700, 'Parse error');
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const rpcId = rpc.id ?? null;
|
|
147
|
+
switch (rpc.method) {
|
|
148
|
+
case 'tasks/send':
|
|
149
|
+
await this.handleSend(res, rpcId, rpc);
|
|
150
|
+
return;
|
|
151
|
+
case 'tasks/get':
|
|
152
|
+
this.handleGet(res, rpcId, rpc);
|
|
153
|
+
return;
|
|
154
|
+
case 'tasks/cancel':
|
|
155
|
+
this.handleCancel(res, rpcId, rpc);
|
|
156
|
+
return;
|
|
157
|
+
default:
|
|
158
|
+
this.rpcError(res, rpcId, -32601, `Method not found: ${rpc.method ?? '(none)'}`);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
this.json(res, 404, { error: 'not found' });
|
|
163
|
+
}
|
|
164
|
+
// --------------------------------------------------------------------------
|
|
165
|
+
// JSON-RPC methods
|
|
166
|
+
// --------------------------------------------------------------------------
|
|
167
|
+
async handleSend(res, rpcId, rpc) {
|
|
168
|
+
const params = rpc.params;
|
|
169
|
+
const parts = params?.message?.parts ?? [];
|
|
170
|
+
const text = parts
|
|
171
|
+
.filter((p) => p.type === 'text' && typeof p.text === 'string')
|
|
172
|
+
.map((p) => p.text)
|
|
173
|
+
.join('\n');
|
|
174
|
+
if (!text) {
|
|
175
|
+
this.rpcError(res, rpcId, -32602, 'Invalid params: message must contain at least one text part');
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
const taskId = params?.id && typeof params.id === 'string' ? params.id : (0, crypto_1.randomUUID)();
|
|
179
|
+
const task = {
|
|
180
|
+
id: taskId,
|
|
181
|
+
state: 'working',
|
|
182
|
+
input: text.slice(0, 10_000),
|
|
183
|
+
createdAt: Date.now(),
|
|
184
|
+
};
|
|
185
|
+
this.store(task);
|
|
186
|
+
try {
|
|
187
|
+
const result = await this.options.executor(text, params?.metadata);
|
|
188
|
+
task.state = 'completed';
|
|
189
|
+
task.output = result.text ?? (result.data !== undefined ? JSON.stringify(result.data) : '');
|
|
190
|
+
task.resolvedAt = Date.now();
|
|
191
|
+
this.json(res, 200, {
|
|
192
|
+
jsonrpc: '2.0',
|
|
193
|
+
id: rpcId,
|
|
194
|
+
result: {
|
|
195
|
+
id: taskId,
|
|
196
|
+
status: { state: 'completed' },
|
|
197
|
+
artifacts: [{
|
|
198
|
+
name: 'result',
|
|
199
|
+
parts: [{ type: 'text', text: task.output }],
|
|
200
|
+
}],
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
task.state = 'failed';
|
|
206
|
+
task.message = err instanceof Error ? err.message : String(err);
|
|
207
|
+
task.resolvedAt = Date.now();
|
|
208
|
+
this.json(res, 200, {
|
|
209
|
+
jsonrpc: '2.0',
|
|
210
|
+
id: rpcId,
|
|
211
|
+
result: {
|
|
212
|
+
id: taskId,
|
|
213
|
+
status: { state: 'failed', message: task.message },
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
handleGet(res, rpcId, rpc) {
|
|
219
|
+
const id = rpc.params?.id;
|
|
220
|
+
const task = id ? this.tasks.get(id) : undefined;
|
|
221
|
+
if (!task) {
|
|
222
|
+
this.rpcError(res, rpcId, -32001, `Task not found: ${id ?? '(none)'}`);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
this.json(res, 200, {
|
|
226
|
+
jsonrpc: '2.0',
|
|
227
|
+
id: rpcId,
|
|
228
|
+
result: {
|
|
229
|
+
id: task.id,
|
|
230
|
+
status: { state: task.state, ...(task.message ? { message: task.message } : {}) },
|
|
231
|
+
...(task.output !== undefined
|
|
232
|
+
? { artifacts: [{ name: 'result', parts: [{ type: 'text', text: task.output }] }] }
|
|
233
|
+
: {}),
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
handleCancel(res, rpcId, rpc) {
|
|
238
|
+
const id = rpc.params?.id;
|
|
239
|
+
const task = id ? this.tasks.get(id) : undefined;
|
|
240
|
+
if (!task) {
|
|
241
|
+
this.rpcError(res, rpcId, -32001, `Task not found: ${id ?? '(none)'}`);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (task.state === 'submitted' || task.state === 'working') {
|
|
245
|
+
task.state = 'canceled';
|
|
246
|
+
task.resolvedAt = Date.now();
|
|
247
|
+
}
|
|
248
|
+
this.json(res, 200, {
|
|
249
|
+
jsonrpc: '2.0',
|
|
250
|
+
id: rpcId,
|
|
251
|
+
result: { id: task.id, status: { state: task.state } },
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
// --------------------------------------------------------------------------
|
|
255
|
+
// Helpers
|
|
256
|
+
// --------------------------------------------------------------------------
|
|
257
|
+
store(task) {
|
|
258
|
+
this.tasks.set(task.id, task);
|
|
259
|
+
if (this.tasks.size > this.options.maxHistory) {
|
|
260
|
+
const oldest = this.tasks.keys().next().value;
|
|
261
|
+
if (oldest !== undefined)
|
|
262
|
+
this.tasks.delete(oldest);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
readBody(req) {
|
|
266
|
+
return new Promise((resolve, reject) => {
|
|
267
|
+
let size = 0;
|
|
268
|
+
const chunks = [];
|
|
269
|
+
req.on('data', (chunk) => {
|
|
270
|
+
size += chunk.length;
|
|
271
|
+
if (size > this.options.maxBodyBytes) {
|
|
272
|
+
reject(new Error(`request body exceeds ${this.options.maxBodyBytes} bytes`));
|
|
273
|
+
req.destroy();
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
chunks.push(chunk);
|
|
277
|
+
});
|
|
278
|
+
req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
279
|
+
req.on('error', reject);
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
json(res, status, payload) {
|
|
283
|
+
if (res.writableEnded)
|
|
284
|
+
return;
|
|
285
|
+
res.writeHead(status, { 'Content-Type': 'application/json' });
|
|
286
|
+
res.end(JSON.stringify(payload));
|
|
287
|
+
}
|
|
288
|
+
rpcError(res, id, code, message) {
|
|
289
|
+
this.json(res, 200, { jsonrpc: '2.0', id, error: { code, message } });
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
exports.A2AServer = A2AServer;
|
|
293
|
+
//# sourceMappingURL=a2a-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a2a-server.js","sourceRoot":"","sources":["../../lib/a2a-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code Hooks Bridge — AuthGuardian-gated tool calls for coding agents.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code (and other hook-capable agent CLIs) can call an external
|
|
5
|
+
* command on every tool use (PreToolUse / PostToolUse hooks). This module
|
|
6
|
+
* turns Network-AI into that command: every tool call an agent makes is
|
|
7
|
+
* audited — and optionally permission-gated — through the same
|
|
8
|
+
* `AuthGuardian` weighted scoring used for swarm agents (justification 40%,
|
|
9
|
+
* trust 30%, risk 30%).
|
|
10
|
+
*
|
|
11
|
+
* Two modes:
|
|
12
|
+
* - `'observe'` (default) — every tool call is audit-logged, nothing is
|
|
13
|
+
* blocked. Zero-risk visibility into what the agent is doing.
|
|
14
|
+
* - `'enforce'` — tool calls are mapped to Network-AI resource types
|
|
15
|
+
* (Bash → SHELL_EXEC, Write/Edit → FILE_SYSTEM, WebFetch →
|
|
16
|
+
* EXTERNAL_SERVICE, …) and must pass `AuthGuardian.requestPermission()`.
|
|
17
|
+
* Denied calls return `'ask'` (escalate to the human) or `'deny'`.
|
|
18
|
+
*
|
|
19
|
+
* Wire-up (Claude Code `settings.json`):
|
|
20
|
+
* ```json
|
|
21
|
+
* {
|
|
22
|
+
* "hooks": {
|
|
23
|
+
* "PreToolUse": [{
|
|
24
|
+
* "matcher": "Bash|Write|Edit|WebFetch",
|
|
25
|
+
* "hooks": [{ "type": "command",
|
|
26
|
+
* "command": "npx -y -p network-ai network-ai hook pre-tool-use --mode enforce" }]
|
|
27
|
+
* }]
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* ```
|
|
31
|
+
* See `examples/claude-code-hooks.json` for a complete config.
|
|
32
|
+
*
|
|
33
|
+
* @module ClaudeHooks
|
|
34
|
+
* @version 1.0.0
|
|
35
|
+
*/
|
|
36
|
+
import { AuthGuardian } from './auth-guardian';
|
|
37
|
+
/** Hook events supported by the bridge */
|
|
38
|
+
export type ClaudeHookEvent = 'PreToolUse' | 'PostToolUse';
|
|
39
|
+
/** JSON payload Claude Code writes to the hook's stdin */
|
|
40
|
+
export interface ClaudeHookInput {
|
|
41
|
+
/** Claude Code session identifier */
|
|
42
|
+
session_id?: string;
|
|
43
|
+
/** Path to the session transcript */
|
|
44
|
+
transcript_path?: string;
|
|
45
|
+
/** Working directory of the session */
|
|
46
|
+
cwd?: string;
|
|
47
|
+
/** Which hook event fired */
|
|
48
|
+
hook_event_name: string;
|
|
49
|
+
/** Tool being invoked — e.g. 'Bash', 'Write', 'mcp__github__create_issue' */
|
|
50
|
+
tool_name?: string;
|
|
51
|
+
/** Tool input parameters (shape depends on the tool) */
|
|
52
|
+
tool_input?: Record<string, unknown>;
|
|
53
|
+
/** Tool response (PostToolUse only) */
|
|
54
|
+
tool_response?: unknown;
|
|
55
|
+
}
|
|
56
|
+
/** Permission decision for a PreToolUse hook */
|
|
57
|
+
export type HookPermissionDecision = 'allow' | 'deny' | 'ask';
|
|
58
|
+
/** JSON the bridge writes to stdout for PreToolUse */
|
|
59
|
+
export interface PreToolUseHookOutput {
|
|
60
|
+
hookSpecificOutput: {
|
|
61
|
+
hookEventName: 'PreToolUse';
|
|
62
|
+
permissionDecision: HookPermissionDecision;
|
|
63
|
+
permissionDecisionReason: string;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/** Audit entry emitted for every processed hook call */
|
|
67
|
+
export interface HookAuditEntry {
|
|
68
|
+
timestamp: string;
|
|
69
|
+
event: ClaudeHookEvent;
|
|
70
|
+
toolName: string;
|
|
71
|
+
target: string;
|
|
72
|
+
decision?: HookPermissionDecision;
|
|
73
|
+
reason?: string;
|
|
74
|
+
sessionId?: string;
|
|
75
|
+
agentId: string;
|
|
76
|
+
mode: 'observe' | 'enforce';
|
|
77
|
+
}
|
|
78
|
+
/** Options for the ClaudeHookBridge */
|
|
79
|
+
export interface ClaudeHookBridgeOptions {
|
|
80
|
+
/** Existing AuthGuardian to gate through. Auto-created in enforce mode if omitted. */
|
|
81
|
+
guardian?: AuthGuardian;
|
|
82
|
+
/** Agent identity used for permission requests (default: 'claude-code') */
|
|
83
|
+
agentId?: string;
|
|
84
|
+
/** 'observe' (audit only, default) or 'enforce' (AuthGuardian-gated) */
|
|
85
|
+
mode?: 'observe' | 'enforce';
|
|
86
|
+
/** Trust level for the auto-created guardian identity (default: 0.7) */
|
|
87
|
+
trustLevel?: number;
|
|
88
|
+
/** Tool names / targets matching any of these are denied outright (checked first) */
|
|
89
|
+
denyPatterns?: Array<string | RegExp>;
|
|
90
|
+
/** Tool names / targets matching any of these are allowed without gating */
|
|
91
|
+
allowPatterns?: Array<string | RegExp>;
|
|
92
|
+
/** Override the tool → resource-type mapping (merged over the defaults) */
|
|
93
|
+
toolResourceMap?: Record<string, string>;
|
|
94
|
+
/** Decision to return when the guardian denies: 'ask' escalates to the human (default), 'deny' blocks */
|
|
95
|
+
blockedDecision?: 'deny' | 'ask';
|
|
96
|
+
/** JSONL file to append hook audit entries to (observe mode has no guardian log) */
|
|
97
|
+
auditLogPath?: string;
|
|
98
|
+
/** Audit log path for the auto-created guardian (defaults to AuthGuardian's standard path) */
|
|
99
|
+
guardianAuditLogPath?: string;
|
|
100
|
+
/** Trust config path for the auto-created guardian */
|
|
101
|
+
trustConfigPath?: string;
|
|
102
|
+
/** Callback invoked with every audit entry */
|
|
103
|
+
onAudit?: (entry: HookAuditEntry) => void;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Default mapping from Claude Code tool names to Network-AI resource types.
|
|
107
|
+
* MCP tools (`mcp__*`) and unknown tools map to EXTERNAL_SERVICE.
|
|
108
|
+
*/
|
|
109
|
+
export declare const DEFAULT_TOOL_RESOURCE_MAP: Record<string, string>;
|
|
110
|
+
/**
|
|
111
|
+
* Bridges coding-agent hook events (Claude Code PreToolUse / PostToolUse)
|
|
112
|
+
* into Network-AI's AuthGuardian permission system and audit trail.
|
|
113
|
+
*/
|
|
114
|
+
export declare class ClaudeHookBridge {
|
|
115
|
+
private readonly guardian;
|
|
116
|
+
private readonly agentId;
|
|
117
|
+
private readonly mode;
|
|
118
|
+
private readonly denyPatterns;
|
|
119
|
+
private readonly allowPatterns;
|
|
120
|
+
private readonly toolResourceMap;
|
|
121
|
+
private readonly blockedDecision;
|
|
122
|
+
private readonly auditLogPath;
|
|
123
|
+
private readonly onAudit;
|
|
124
|
+
constructor(options?: ClaudeHookBridgeOptions);
|
|
125
|
+
/**
|
|
126
|
+
* Parse a raw hook stdin payload. Tolerates a leading UTF-8 BOM (some
|
|
127
|
+
* shells prepend one when piping). Throws on malformed JSON or a payload
|
|
128
|
+
* that is not an object.
|
|
129
|
+
*/
|
|
130
|
+
static parseInput(raw: string): ClaudeHookInput;
|
|
131
|
+
/**
|
|
132
|
+
* Handle a PreToolUse event: decide allow / deny / ask.
|
|
133
|
+
*
|
|
134
|
+
* Decision order: denyPatterns → allowPatterns → observe-mode allow →
|
|
135
|
+
* AuthGuardian permission request (enforce mode).
|
|
136
|
+
*/
|
|
137
|
+
handlePreToolUse(input: ClaudeHookInput): Promise<PreToolUseHookOutput>;
|
|
138
|
+
/**
|
|
139
|
+
* Handle a PostToolUse event: audit the completed call. Never blocks.
|
|
140
|
+
* Returns an empty object (the hook-protocol no-op).
|
|
141
|
+
*/
|
|
142
|
+
handlePostToolUse(input: ClaudeHookInput): Promise<Record<string, never>>;
|
|
143
|
+
/**
|
|
144
|
+
* Dispatch a hook input by its `hook_event_name`.
|
|
145
|
+
*/
|
|
146
|
+
handle(input: ClaudeHookInput): Promise<PreToolUseHookOutput | Record<string, never>>;
|
|
147
|
+
private decide;
|
|
148
|
+
private audit;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=claude-hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-hooks.d.ts","sourceRoot":"","sources":["../../lib/claude-hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAM/C,0CAA0C;AAC1C,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG,aAAa,CAAC;AAE3D,0DAA0D;AAC1D,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uCAAuC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6BAA6B;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,uCAAuC;IACvC,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,gDAAgD;AAChD,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AAE9D,sDAAsD;AACtD,MAAM,WAAW,oBAAoB;IACnC,kBAAkB,EAAE;QAClB,aAAa,EAAE,YAAY,CAAC;QAC5B,kBAAkB,EAAE,sBAAsB,CAAC;QAC3C,wBAAwB,EAAE,MAAM,CAAC;KAClC,CAAC;CACH;AAED,wDAAwD;AACxD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,SAAS,GAAG,SAAS,CAAC;CAC7B;AAED,uCAAuC;AACvC,MAAM,WAAW,uBAAuB;IACtC,sFAAsF;IACtF,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAC7B,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qFAAqF;IACrF,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACtC,4EAA4E;IAC5E,aAAa,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACvC,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,yGAAyG;IACzG,eAAe,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACjC,oFAAoF;IACpF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8FAA8F;IAC9F,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,sDAAsD;IACtD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;CAC3C;AAMD;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAc5D,CAAC;AAgDF;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAwB;IAC7C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyB;IACtD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IACvD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAyB;IACzD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;gBAEvD,OAAO,GAAE,uBAA4B;IA6BjD;;;;OAIG;IACH,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe;IAkB/C;;;;;OAKG;IACG,gBAAgB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAwC7E;;;OAGG;IACG,iBAAiB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAe/E;;OAEG;IACG,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAU3F,OAAO,CAAC,MAAM;IA2Bd,OAAO,CAAC,KAAK;CAed"}
|