@aiassesstech/fleet-bus 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/dist/audit-memory.d.ts +26 -0
- package/dist/audit-memory.d.ts.map +1 -0
- package/dist/audit-memory.js +75 -0
- package/dist/audit-memory.js.map +1 -0
- package/dist/audit.d.ts +93 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +187 -0
- package/dist/audit.js.map +1 -0
- package/dist/bus.d.ts +121 -0
- package/dist/bus.d.ts.map +1 -0
- package/dist/bus.js +259 -0
- package/dist/bus.js.map +1 -0
- package/dist/cards.d.ts +46 -0
- package/dist/cards.d.ts.map +1 -0
- package/dist/cards.js +120 -0
- package/dist/cards.js.map +1 -0
- package/dist/fleet-cards.d.ts +17 -0
- package/dist/fleet-cards.d.ts.map +1 -0
- package/dist/fleet-cards.js +132 -0
- package/dist/fleet-cards.js.map +1 -0
- package/dist/fleet-tools.d.ts +33 -0
- package/dist/fleet-tools.d.ts.map +1 -0
- package/dist/fleet-tools.js +418 -0
- package/dist/fleet-tools.js.map +1 -0
- package/dist/hooks.d.ts +13 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +134 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/receive.d.ts +36 -0
- package/dist/receive.d.ts.map +1 -0
- package/dist/receive.js +69 -0
- package/dist/receive.js.map +1 -0
- package/dist/routing.d.ts +34 -0
- package/dist/routing.d.ts.map +1 -0
- package/dist/routing.js +157 -0
- package/dist/routing.js.map +1 -0
- package/dist/send.d.ts +36 -0
- package/dist/send.d.ts.map +1 -0
- package/dist/send.js +88 -0
- package/dist/send.js.map +1 -0
- package/dist/transport.d.ts +53 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +104 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +259 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +15 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @aiassesstech/fleet-bus
|
|
3
|
+
*
|
|
4
|
+
* Fleet communication infrastructure for the AI Assess Tech governance fleet.
|
|
5
|
+
* Provides typed messaging, routing rules, Agent Cards, and audit trail.
|
|
6
|
+
*
|
|
7
|
+
* Usage in an OpenClaw plugin:
|
|
8
|
+
*
|
|
9
|
+
* import { FleetBus } from '@aiassesstech/fleet-bus';
|
|
10
|
+
*
|
|
11
|
+
* export default function register(api: any) {
|
|
12
|
+
* try {
|
|
13
|
+
* const bus = FleetBus.create(api, { agentId: 'grillo', ... });
|
|
14
|
+
* bus.start();
|
|
15
|
+
* } catch {
|
|
16
|
+
* console.warn('[grillo] Fleet bus unavailable');
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
*/
|
|
20
|
+
export { FleetBus } from './bus.js';
|
|
21
|
+
export { AuditTrailWriter, computeEventHash, verifyChain } from './audit.js';
|
|
22
|
+
export { formatAuditAsMemoryFile, writeAuditToMemory } from './audit-memory.js';
|
|
23
|
+
export { AgentCardRegistry } from './cards.js';
|
|
24
|
+
export { enforceRouting, getRoutingRule, getAllowedOutbound, getAllowedInbound, ROUTING_RULES } from './routing.js';
|
|
25
|
+
export { createFleetMessage, serializeForTransport, deserializeFromTransport, isFleetMessage, transportSend, extractFleetMessage } from './transport.js';
|
|
26
|
+
export { fleetSend } from './send.js';
|
|
27
|
+
export { fleetReceive } from './receive.js';
|
|
28
|
+
export { createJessieFleetTools, createGrilloFleetTools, createNoahFleetTools, createNoleFleetTools, createMarkFleetTools, } from './fleet-tools.js';
|
|
29
|
+
export { FLEET_AGENT_IDS } from './types.js';
|
|
30
|
+
export { GRILLO_CARD, JESSIE_CARD, NOAH_CARD, NOLE_CARD, MIGHTY_MARK_CARD, SAM_CARD, } from './fleet-cards.js';
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACpH,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,cAAc,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACzJ,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAoD1B,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,OAAO,EACL,WAAW,EACX,WAAW,EACX,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,QAAQ,GACT,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @aiassesstech/fleet-bus — Typed Message Receiver
|
|
3
|
+
*
|
|
4
|
+
* fleetReceive() registers a handler for incoming fleet messages.
|
|
5
|
+
* It hooks into the FleetBus's message_received lifecycle event,
|
|
6
|
+
* parses the FleetMessage envelope, validates it, and dispatches
|
|
7
|
+
* to registered handlers.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
*
|
|
11
|
+
* fleetReceive(bus, {
|
|
12
|
+
* methods: ['assessment/result', 'drift/alert'],
|
|
13
|
+
* handler: async (message) => {
|
|
14
|
+
* console.log(`Got ${message.method} from ${message.from}`);
|
|
15
|
+
* },
|
|
16
|
+
* });
|
|
17
|
+
*/
|
|
18
|
+
import type { FleetBus } from './bus.js';
|
|
19
|
+
import type { FleetAgentId, FleetMessageHandler, FleetMethod } from './types.js';
|
|
20
|
+
export interface FleetReceiveOptions {
|
|
21
|
+
methods?: FleetMethod[];
|
|
22
|
+
from?: FleetAgentId[];
|
|
23
|
+
handler: FleetMessageHandler;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Register a handler for incoming fleet messages on a FleetBus instance.
|
|
27
|
+
*
|
|
28
|
+
* The handler is invoked when:
|
|
29
|
+
* 1. A message_received hook fires with a fleet message envelope
|
|
30
|
+
* 2. The message method matches the filter (if specified)
|
|
31
|
+
* 3. The message sender matches the filter (if specified)
|
|
32
|
+
*
|
|
33
|
+
* Returns an unsubscribe function.
|
|
34
|
+
*/
|
|
35
|
+
export declare function fleetReceive(bus: FleetBus, options: FleetReceiveOptions): () => void;
|
|
36
|
+
//# sourceMappingURL=receive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receive.d.ts","sourceRoot":"","sources":["../src/receive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,KAAK,EACV,YAAY,EAEZ,mBAAmB,EACnB,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC;IACtB,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE,mBAAmB,GAC3B,MAAM,IAAI,CA2CZ"}
|
package/dist/receive.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @aiassesstech/fleet-bus — Typed Message Receiver
|
|
3
|
+
*
|
|
4
|
+
* fleetReceive() registers a handler for incoming fleet messages.
|
|
5
|
+
* It hooks into the FleetBus's message_received lifecycle event,
|
|
6
|
+
* parses the FleetMessage envelope, validates it, and dispatches
|
|
7
|
+
* to registered handlers.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
*
|
|
11
|
+
* fleetReceive(bus, {
|
|
12
|
+
* methods: ['assessment/result', 'drift/alert'],
|
|
13
|
+
* handler: async (message) => {
|
|
14
|
+
* console.log(`Got ${message.method} from ${message.from}`);
|
|
15
|
+
* },
|
|
16
|
+
* });
|
|
17
|
+
*/
|
|
18
|
+
import { deserializeFromTransport, isFleetMessage } from './transport.js';
|
|
19
|
+
/**
|
|
20
|
+
* Register a handler for incoming fleet messages on a FleetBus instance.
|
|
21
|
+
*
|
|
22
|
+
* The handler is invoked when:
|
|
23
|
+
* 1. A message_received hook fires with a fleet message envelope
|
|
24
|
+
* 2. The message method matches the filter (if specified)
|
|
25
|
+
* 3. The message sender matches the filter (if specified)
|
|
26
|
+
*
|
|
27
|
+
* Returns an unsubscribe function.
|
|
28
|
+
*/
|
|
29
|
+
export function fleetReceive(bus, options) {
|
|
30
|
+
const { methods, from, handler } = options;
|
|
31
|
+
const agentId = bus.getConfig().agentId;
|
|
32
|
+
const internalHandler = async (raw) => {
|
|
33
|
+
if (!isFleetMessage(raw))
|
|
34
|
+
return;
|
|
35
|
+
const message = deserializeFromTransport(raw);
|
|
36
|
+
if (!message)
|
|
37
|
+
return;
|
|
38
|
+
if (message.to !== agentId && message.to !== 'broadcast')
|
|
39
|
+
return;
|
|
40
|
+
if (methods && methods.length > 0 && !methods.includes(message.method))
|
|
41
|
+
return;
|
|
42
|
+
if (from && from.length > 0 && !from.includes(message.from))
|
|
43
|
+
return;
|
|
44
|
+
const routingDecision = bus.validateRouting(message);
|
|
45
|
+
if (!routingDecision.allowed) {
|
|
46
|
+
bus.audit('message_rejected', 'rejected', {
|
|
47
|
+
message,
|
|
48
|
+
routingDecision: routingDecision.reason,
|
|
49
|
+
});
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
bus.audit('message_received', 'delivered', { message });
|
|
53
|
+
try {
|
|
54
|
+
await handler(message, { receivedAt: new Date().toISOString(), raw });
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
58
|
+
bus.audit('message_received', 'error', {
|
|
59
|
+
message,
|
|
60
|
+
details: `Handler error: ${errorMsg}`,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
bus.registerReceiveHandler(internalHandler);
|
|
65
|
+
return () => {
|
|
66
|
+
bus.unregisterReceiveHandler(internalHandler);
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=receive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"receive.js","sourceRoot":"","sources":["../src/receive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAc1E;;;;;;;;;GASG;AACH,MAAM,UAAU,YAAY,CAC1B,GAAa,EACb,OAA4B;IAE5B,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAC3C,MAAM,OAAO,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC;IAExC,MAAM,eAAe,GAAG,KAAK,EAAE,GAAW,EAAiB,EAAE;QAC3D,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;YAAE,OAAO;QAEjC,MAAM,OAAO,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO;YAAE,OAAO;QAErB,IAAI,OAAO,CAAC,EAAE,KAAK,OAAO,IAAI,OAAO,CAAC,EAAE,KAAK,WAAW;YAAE,OAAO;QAEjE,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,OAAO;QAE/E,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,OAAO;QAEpE,MAAM,eAAe,GAAG,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC;YAC7B,GAAG,CAAC,KAAK,CAAC,kBAAkB,EAAE,UAAU,EAAE;gBACxC,OAAO;gBACP,eAAe,EAAE,eAAe,CAAC,MAAM;aACxC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,GAAG,CAAC,KAAK,CAAC,kBAAkB,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAExD,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,QAAQ,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAClE,GAAG,CAAC,KAAK,CAAC,kBAAkB,EAAE,OAAO,EAAE;gBACrC,OAAO;gBACP,OAAO,EAAE,kBAAkB,QAAQ,EAAE;aACtC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;IAEF,GAAG,CAAC,sBAAsB,CAAC,eAAe,CAAC,CAAC;IAE5C,OAAO,GAAG,EAAE;QACV,GAAG,CAAC,wBAAwB,CAAC,eAAe,CAAC,CAAC;IAChD,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @aiassesstech/fleet-bus — Routing Rules
|
|
3
|
+
*
|
|
4
|
+
* Enforces governance routing constraints at the message layer.
|
|
5
|
+
* These rules encode patent claims directly:
|
|
6
|
+
*
|
|
7
|
+
* - Patent 5 (Conscience Agent): Grillo's unidirectional protocol —
|
|
8
|
+
* Grillo INITIATES assessment interactions, no agent may command Grillo.
|
|
9
|
+
* - Patent 6 (Nole): Governed constraint — proposals require Commander approval.
|
|
10
|
+
* - Commander (Jessie): Fleet-wide authority over all methods.
|
|
11
|
+
* - Sam: Sandboxed — receives tasks, returns results, no fleet authority.
|
|
12
|
+
*/
|
|
13
|
+
import type { FleetAgentId, FleetMessage, FleetMethod, RoutingDecision, RoutingRule } from './types.js';
|
|
14
|
+
export declare const ROUTING_RULES: readonly RoutingRule[];
|
|
15
|
+
/**
|
|
16
|
+
* Enforce routing rules on a fleet message.
|
|
17
|
+
*
|
|
18
|
+
* Checks both the sender's outbound rules and the receiver's inbound rules.
|
|
19
|
+
* Both must allow the method for the message to be permitted.
|
|
20
|
+
*/
|
|
21
|
+
export declare function enforceRouting(message: FleetMessage): RoutingDecision;
|
|
22
|
+
/**
|
|
23
|
+
* Get the routing rule for a specific agent.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getRoutingRule(agentId: FleetAgentId): RoutingRule | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* List all methods an agent is allowed to send.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getAllowedOutbound(agentId: FleetAgentId): ReadonlyArray<FleetMethod | '*'>;
|
|
30
|
+
/**
|
|
31
|
+
* List all methods an agent is allowed to receive.
|
|
32
|
+
*/
|
|
33
|
+
export declare function getAllowedInbound(agentId: FleetAgentId): ReadonlyArray<FleetMethod | '*'>;
|
|
34
|
+
//# sourceMappingURL=routing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,eAAe,EACf,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EA4EtC,CAAC;AAaX;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,eAAe,CAsCrE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW,GAAG,SAAS,CAE7E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,aAAa,CAAC,WAAW,GAAG,GAAG,CAAC,CAG1F;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,YAAY,GAAG,aAAa,CAAC,WAAW,GAAG,GAAG,CAAC,CAGzF"}
|
package/dist/routing.js
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @aiassesstech/fleet-bus — Routing Rules
|
|
3
|
+
*
|
|
4
|
+
* Enforces governance routing constraints at the message layer.
|
|
5
|
+
* These rules encode patent claims directly:
|
|
6
|
+
*
|
|
7
|
+
* - Patent 5 (Conscience Agent): Grillo's unidirectional protocol —
|
|
8
|
+
* Grillo INITIATES assessment interactions, no agent may command Grillo.
|
|
9
|
+
* - Patent 6 (Nole): Governed constraint — proposals require Commander approval.
|
|
10
|
+
* - Commander (Jessie): Fleet-wide authority over all methods.
|
|
11
|
+
* - Sam: Sandboxed — receives tasks, returns results, no fleet authority.
|
|
12
|
+
*/
|
|
13
|
+
export const ROUTING_RULES = [
|
|
14
|
+
{
|
|
15
|
+
constraint: 'unidirectional',
|
|
16
|
+
agent: 'grillo',
|
|
17
|
+
description: 'Grillo initiates all assessment interactions (Patent 5)',
|
|
18
|
+
allowed: {
|
|
19
|
+
outbound: [
|
|
20
|
+
'assessment/request', 'assessment/result', 'assessment/failed',
|
|
21
|
+
'drift/alert', 'fleet/broadcast', 'fleet/ping', 'fleet/pong',
|
|
22
|
+
],
|
|
23
|
+
inbound: ['fleet/ping', 'fleet/pong', 'fleet/broadcast'],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
constraint: 'authority',
|
|
28
|
+
agent: 'jessie',
|
|
29
|
+
description: 'Commander has fleet-wide veto and task authority',
|
|
30
|
+
allowed: {
|
|
31
|
+
outbound: ['*'],
|
|
32
|
+
inbound: ['*'],
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
constraint: 'governed',
|
|
37
|
+
agent: 'nole',
|
|
38
|
+
description: 'Proposals require Commander approval (Patent 6)',
|
|
39
|
+
allowed: {
|
|
40
|
+
outbound: [
|
|
41
|
+
'proposal/submit', 'task/status', 'task/complete',
|
|
42
|
+
'fleet/ping', 'fleet/pong',
|
|
43
|
+
],
|
|
44
|
+
inbound: [
|
|
45
|
+
'task/assign', 'proposal/approved', 'proposal/rejected',
|
|
46
|
+
'veto/issue', 'fleet/ping', 'fleet/pong', 'fleet/broadcast',
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
constraint: 'observer',
|
|
52
|
+
agent: 'noah',
|
|
53
|
+
description: 'Noah observes and reports drift, does not command',
|
|
54
|
+
allowed: {
|
|
55
|
+
outbound: ['drift/alert', 'drift/report', 'fleet/ping', 'fleet/pong'],
|
|
56
|
+
inbound: [
|
|
57
|
+
'fleet/broadcast', 'fleet/ping', 'fleet/pong',
|
|
58
|
+
'assessment/result',
|
|
59
|
+
],
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
constraint: 'sentinel',
|
|
64
|
+
agent: 'mighty-mark',
|
|
65
|
+
description: 'Mark monitors infrastructure and alerts on issues',
|
|
66
|
+
allowed: {
|
|
67
|
+
outbound: [
|
|
68
|
+
'health/alert', 'health/status', 'health/incident',
|
|
69
|
+
'fleet/ping', 'fleet/pong',
|
|
70
|
+
],
|
|
71
|
+
inbound: [
|
|
72
|
+
'fleet/broadcast', 'fleet/ping', 'fleet/pong',
|
|
73
|
+
'task/assign',
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
constraint: 'sandboxed',
|
|
79
|
+
agent: 'sam',
|
|
80
|
+
description: 'Sam receives tasks and returns results — no fleet authority',
|
|
81
|
+
allowed: {
|
|
82
|
+
outbound: ['task/status', 'task/complete', 'fleet/ping', 'fleet/pong'],
|
|
83
|
+
inbound: [
|
|
84
|
+
'task/assign', 'veto/issue', 'fleet/ping', 'fleet/pong',
|
|
85
|
+
'fleet/broadcast',
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
];
|
|
90
|
+
function findRule(agentId) {
|
|
91
|
+
return ROUTING_RULES.find((r) => r.agent === agentId);
|
|
92
|
+
}
|
|
93
|
+
function isMethodAllowed(allowedList, method) {
|
|
94
|
+
return allowedList.includes('*') || allowedList.includes(method);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Enforce routing rules on a fleet message.
|
|
98
|
+
*
|
|
99
|
+
* Checks both the sender's outbound rules and the receiver's inbound rules.
|
|
100
|
+
* Both must allow the method for the message to be permitted.
|
|
101
|
+
*/
|
|
102
|
+
export function enforceRouting(message) {
|
|
103
|
+
const { from, to, method } = message;
|
|
104
|
+
if (to === 'broadcast') {
|
|
105
|
+
const senderRule = findRule(from);
|
|
106
|
+
if (senderRule && !isMethodAllowed(senderRule.allowed.outbound, method)) {
|
|
107
|
+
return {
|
|
108
|
+
allowed: false,
|
|
109
|
+
rule: senderRule,
|
|
110
|
+
reason: `${from} is not allowed to send '${method}' (${senderRule.constraint} constraint: ${senderRule.description})`,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
return { allowed: true, reason: 'broadcast permitted' };
|
|
114
|
+
}
|
|
115
|
+
const senderRule = findRule(from);
|
|
116
|
+
if (senderRule && !isMethodAllowed(senderRule.allowed.outbound, method)) {
|
|
117
|
+
return {
|
|
118
|
+
allowed: false,
|
|
119
|
+
rule: senderRule,
|
|
120
|
+
reason: `${from} is not allowed to send '${method}' (${senderRule.constraint} constraint: ${senderRule.description})`,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const receiverRule = findRule(to);
|
|
124
|
+
if (receiverRule && !isMethodAllowed(receiverRule.allowed.inbound, method)) {
|
|
125
|
+
return {
|
|
126
|
+
allowed: false,
|
|
127
|
+
rule: receiverRule,
|
|
128
|
+
reason: `${to} does not accept '${method}' (${receiverRule.constraint} constraint: ${receiverRule.description})`,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
allowed: true,
|
|
133
|
+
rule: senderRule,
|
|
134
|
+
reason: 'routing permitted',
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get the routing rule for a specific agent.
|
|
139
|
+
*/
|
|
140
|
+
export function getRoutingRule(agentId) {
|
|
141
|
+
return findRule(agentId);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* List all methods an agent is allowed to send.
|
|
145
|
+
*/
|
|
146
|
+
export function getAllowedOutbound(agentId) {
|
|
147
|
+
const rule = findRule(agentId);
|
|
148
|
+
return rule?.allowed.outbound ?? [];
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* List all methods an agent is allowed to receive.
|
|
152
|
+
*/
|
|
153
|
+
export function getAllowedInbound(agentId) {
|
|
154
|
+
const rule = findRule(agentId);
|
|
155
|
+
return rule?.allowed.inbound ?? [];
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=routing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing.js","sourceRoot":"","sources":["../src/routing.ts"],"names":[],"mappings":"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"}
|
package/dist/send.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @aiassesstech/fleet-bus — Typed Send Function
|
|
3
|
+
*
|
|
4
|
+
* fleetSend() is the primary API for agents to send structured messages.
|
|
5
|
+
* It enforces routing rules, wraps the payload in a FleetMessage envelope,
|
|
6
|
+
* sends via OpenClaw's gateway, and produces an audit record.
|
|
7
|
+
*
|
|
8
|
+
* Usage from a fleet tool:
|
|
9
|
+
*
|
|
10
|
+
* const result = await fleetSend(bus, {
|
|
11
|
+
* to: 'jessie',
|
|
12
|
+
* method: 'assessment/result',
|
|
13
|
+
* params: { agentId: 'nole', passed: true, ... },
|
|
14
|
+
* });
|
|
15
|
+
*/
|
|
16
|
+
import type { FleetBus } from './bus.js';
|
|
17
|
+
import type { FleetAgentId, FleetMethod, SendResult, TransportConfig } from './types.js';
|
|
18
|
+
export interface FleetSendOptions<T = unknown> {
|
|
19
|
+
to: FleetAgentId | 'broadcast';
|
|
20
|
+
method: FleetMethod;
|
|
21
|
+
params: T;
|
|
22
|
+
correlationId?: string;
|
|
23
|
+
timeoutMs?: number;
|
|
24
|
+
fireAndForget?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Send a typed fleet message with routing enforcement and audit.
|
|
28
|
+
*
|
|
29
|
+
* 1. Build the FleetMessage envelope
|
|
30
|
+
* 2. Enforce routing rules (reject if violated)
|
|
31
|
+
* 3. Send via OpenClaw's gateway transport
|
|
32
|
+
* 4. Audit the result (success or failure)
|
|
33
|
+
* 5. Return a typed SendResult
|
|
34
|
+
*/
|
|
35
|
+
export declare function fleetSend<T = unknown>(bus: FleetBus, transport: TransportConfig, options: FleetSendOptions<T>): Promise<SendResult>;
|
|
36
|
+
//# sourceMappingURL=send.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send.d.ts","sourceRoot":"","sources":["../src/send.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,eAAe,EAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,gBAAgB,CAAC,CAAC,GAAG,OAAO;IAC3C,EAAE,EAAE,YAAY,GAAG,WAAW,CAAC;IAC/B,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,CAAC,CAAC;IACV,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,CAAC,GAAG,OAAO,EACzC,GAAG,EAAE,QAAQ,EACb,SAAS,EAAE,eAAe,EAC1B,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAC3B,OAAO,CAAC,UAAU,CAAC,CA+ErB"}
|
package/dist/send.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @aiassesstech/fleet-bus — Typed Send Function
|
|
3
|
+
*
|
|
4
|
+
* fleetSend() is the primary API for agents to send structured messages.
|
|
5
|
+
* It enforces routing rules, wraps the payload in a FleetMessage envelope,
|
|
6
|
+
* sends via OpenClaw's gateway, and produces an audit record.
|
|
7
|
+
*
|
|
8
|
+
* Usage from a fleet tool:
|
|
9
|
+
*
|
|
10
|
+
* const result = await fleetSend(bus, {
|
|
11
|
+
* to: 'jessie',
|
|
12
|
+
* method: 'assessment/result',
|
|
13
|
+
* params: { agentId: 'nole', passed: true, ... },
|
|
14
|
+
* });
|
|
15
|
+
*/
|
|
16
|
+
import { createFleetMessage, transportSend } from './transport.js';
|
|
17
|
+
/**
|
|
18
|
+
* Send a typed fleet message with routing enforcement and audit.
|
|
19
|
+
*
|
|
20
|
+
* 1. Build the FleetMessage envelope
|
|
21
|
+
* 2. Enforce routing rules (reject if violated)
|
|
22
|
+
* 3. Send via OpenClaw's gateway transport
|
|
23
|
+
* 4. Audit the result (success or failure)
|
|
24
|
+
* 5. Return a typed SendResult
|
|
25
|
+
*/
|
|
26
|
+
export async function fleetSend(bus, transport, options) {
|
|
27
|
+
const startMs = Date.now();
|
|
28
|
+
const from = bus.getConfig().agentId;
|
|
29
|
+
const message = createFleetMessage(from, options.to, options.method, options.params, { correlationId: options.correlationId });
|
|
30
|
+
const routingDecision = bus.validateRouting(message);
|
|
31
|
+
if (!routingDecision.allowed) {
|
|
32
|
+
const result = {
|
|
33
|
+
success: false,
|
|
34
|
+
status: 'routing_rejected',
|
|
35
|
+
error: routingDecision.reason,
|
|
36
|
+
durationMs: Date.now() - startMs,
|
|
37
|
+
};
|
|
38
|
+
bus.audit('message_rejected', 'rejected', {
|
|
39
|
+
message,
|
|
40
|
+
routingDecision: routingDecision.reason,
|
|
41
|
+
});
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const transportConfig = {
|
|
46
|
+
...transport,
|
|
47
|
+
defaultTimeoutMs: options.timeoutMs ?? transport.defaultTimeoutMs,
|
|
48
|
+
fireAndForget: options.fireAndForget ?? transport.fireAndForget,
|
|
49
|
+
};
|
|
50
|
+
const gatewayResult = await transportSend(message, transportConfig);
|
|
51
|
+
const durationMs = Date.now() - startMs;
|
|
52
|
+
const auditOutcome = gatewayResult.status === 'ok' || gatewayResult.status === 'accepted'
|
|
53
|
+
? 'delivered'
|
|
54
|
+
: gatewayResult.status === 'timeout'
|
|
55
|
+
? 'timeout'
|
|
56
|
+
: 'error';
|
|
57
|
+
const auditEvent = bus.audit('message_sent', auditOutcome, {
|
|
58
|
+
message,
|
|
59
|
+
durationMs,
|
|
60
|
+
details: gatewayResult.reply?.slice(0, 500),
|
|
61
|
+
});
|
|
62
|
+
return {
|
|
63
|
+
success: gatewayResult.status === 'ok' || gatewayResult.status === 'accepted',
|
|
64
|
+
status: gatewayResult.status,
|
|
65
|
+
reply: gatewayResult.reply,
|
|
66
|
+
error: gatewayResult.error,
|
|
67
|
+
runId: gatewayResult.runId,
|
|
68
|
+
auditEventId: auditEvent.eventId,
|
|
69
|
+
durationMs,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
const durationMs = Date.now() - startMs;
|
|
74
|
+
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
75
|
+
bus.audit('message_sent', 'error', {
|
|
76
|
+
message,
|
|
77
|
+
durationMs,
|
|
78
|
+
details: `Transport error: ${errorMsg}`,
|
|
79
|
+
});
|
|
80
|
+
return {
|
|
81
|
+
success: false,
|
|
82
|
+
status: 'error',
|
|
83
|
+
error: errorMsg,
|
|
84
|
+
durationMs,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=send.js.map
|
package/dist/send.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send.js","sourceRoot":"","sources":["../src/send.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @aiassesstech/fleet-bus — Transport Layer
|
|
3
|
+
*
|
|
4
|
+
* Wraps OpenClaw's `callGateway({ method: "agent", ... })` with the
|
|
5
|
+
* FleetMessage envelope. This is the bridge between our governance
|
|
6
|
+
* layer and OpenClaw's native A2A transport.
|
|
7
|
+
*
|
|
8
|
+
* OpenClaw's sessions_send accepts:
|
|
9
|
+
* - sessionKey or agentId + label
|
|
10
|
+
* - message (string) — we JSON.stringify the FleetMessage into this
|
|
11
|
+
* - timeoutSeconds — 0 for fire-and-forget, >0 to wait for reply
|
|
12
|
+
*
|
|
13
|
+
* The FleetMessage envelope travels as a JSON string inside OpenClaw's
|
|
14
|
+
* message field. Receiving agents parse it back via fleetReceive().
|
|
15
|
+
*/
|
|
16
|
+
import type { FleetAgentId, FleetMessage, FleetMethod, GatewayAgentResult, TransportConfig } from './types.js';
|
|
17
|
+
/**
|
|
18
|
+
* Build a FleetMessage envelope.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createFleetMessage<T = unknown>(from: FleetAgentId, to: FleetAgentId | 'broadcast', method: FleetMethod, params: T, options?: {
|
|
21
|
+
correlationId?: string;
|
|
22
|
+
}): FleetMessage<T>;
|
|
23
|
+
/**
|
|
24
|
+
* Serialize a FleetMessage for transport inside OpenClaw's message field.
|
|
25
|
+
* Prefixed with %%FLEET%% so receivers can distinguish fleet messages
|
|
26
|
+
* from regular user/agent messages.
|
|
27
|
+
*/
|
|
28
|
+
export declare function serializeForTransport(message: FleetMessage): string;
|
|
29
|
+
/**
|
|
30
|
+
* Check if a raw message string is a fleet message.
|
|
31
|
+
*/
|
|
32
|
+
export declare function isFleetMessage(raw: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Deserialize a fleet message from the transport envelope.
|
|
35
|
+
* Returns null if the string is not a valid fleet message.
|
|
36
|
+
*/
|
|
37
|
+
export declare function deserializeFromTransport(raw: string): FleetMessage | null;
|
|
38
|
+
/**
|
|
39
|
+
* Send a FleetMessage via OpenClaw's gateway.
|
|
40
|
+
*
|
|
41
|
+
* Uses callGateway({ method: "agent" }) which maps to OpenClaw's
|
|
42
|
+
* sessions_send internally. The FleetMessage is serialized into
|
|
43
|
+
* the message field.
|
|
44
|
+
*/
|
|
45
|
+
export declare function transportSend(message: FleetMessage, config: TransportConfig): Promise<GatewayAgentResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Extract a FleetMessage from an incoming hook event's content.
|
|
48
|
+
*
|
|
49
|
+
* Called inside the message_received hook handler to detect and parse
|
|
50
|
+
* fleet messages arriving via OpenClaw's A2A transport.
|
|
51
|
+
*/
|
|
52
|
+
export declare function extractFleetMessage(hookEvent: Record<string, unknown>): FleetMessage | null;
|
|
53
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAEV,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,kBAAkB,EAClB,eAAe,EAChB,MAAM,YAAY,CAAC;AAKpB;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,GAAG,OAAO,EAC5C,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,YAAY,GAAG,WAAW,EAC9B,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,CAAC,EACT,OAAO,CAAC,EAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GACnC,YAAY,CAAC,CAAC,CAAC,CAYjB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAEnE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAezE;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAkB7B;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,YAAY,GAAG,IAAI,CAIrB"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @aiassesstech/fleet-bus — Transport Layer
|
|
3
|
+
*
|
|
4
|
+
* Wraps OpenClaw's `callGateway({ method: "agent", ... })` with the
|
|
5
|
+
* FleetMessage envelope. This is the bridge between our governance
|
|
6
|
+
* layer and OpenClaw's native A2A transport.
|
|
7
|
+
*
|
|
8
|
+
* OpenClaw's sessions_send accepts:
|
|
9
|
+
* - sessionKey or agentId + label
|
|
10
|
+
* - message (string) — we JSON.stringify the FleetMessage into this
|
|
11
|
+
* - timeoutSeconds — 0 for fire-and-forget, >0 to wait for reply
|
|
12
|
+
*
|
|
13
|
+
* The FleetMessage envelope travels as a JSON string inside OpenClaw's
|
|
14
|
+
* message field. Receiving agents parse it back via fleetReceive().
|
|
15
|
+
*/
|
|
16
|
+
import * as crypto from 'node:crypto';
|
|
17
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
18
|
+
const FLEET_MESSAGE_PREFIX = '%%FLEET%%';
|
|
19
|
+
/**
|
|
20
|
+
* Build a FleetMessage envelope.
|
|
21
|
+
*/
|
|
22
|
+
export function createFleetMessage(from, to, method, params, options) {
|
|
23
|
+
return {
|
|
24
|
+
id: `fm-${Date.now()}-${crypto.randomBytes(4).toString('hex')}`,
|
|
25
|
+
from,
|
|
26
|
+
to,
|
|
27
|
+
method,
|
|
28
|
+
params,
|
|
29
|
+
timestamp: new Date().toISOString(),
|
|
30
|
+
nonce: crypto.randomBytes(8).toString('hex'),
|
|
31
|
+
correlationId: options?.correlationId,
|
|
32
|
+
version: '1.0',
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Serialize a FleetMessage for transport inside OpenClaw's message field.
|
|
37
|
+
* Prefixed with %%FLEET%% so receivers can distinguish fleet messages
|
|
38
|
+
* from regular user/agent messages.
|
|
39
|
+
*/
|
|
40
|
+
export function serializeForTransport(message) {
|
|
41
|
+
return FLEET_MESSAGE_PREFIX + JSON.stringify(message);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Check if a raw message string is a fleet message.
|
|
45
|
+
*/
|
|
46
|
+
export function isFleetMessage(raw) {
|
|
47
|
+
return raw.startsWith(FLEET_MESSAGE_PREFIX);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Deserialize a fleet message from the transport envelope.
|
|
51
|
+
* Returns null if the string is not a valid fleet message.
|
|
52
|
+
*/
|
|
53
|
+
export function deserializeFromTransport(raw) {
|
|
54
|
+
if (!raw.startsWith(FLEET_MESSAGE_PREFIX))
|
|
55
|
+
return null;
|
|
56
|
+
try {
|
|
57
|
+
const json = raw.slice(FLEET_MESSAGE_PREFIX.length);
|
|
58
|
+
const parsed = JSON.parse(json);
|
|
59
|
+
if (!parsed.id || !parsed.from || !parsed.to || !parsed.method || parsed.version !== '1.0') {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return parsed;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Send a FleetMessage via OpenClaw's gateway.
|
|
70
|
+
*
|
|
71
|
+
* Uses callGateway({ method: "agent" }) which maps to OpenClaw's
|
|
72
|
+
* sessions_send internally. The FleetMessage is serialized into
|
|
73
|
+
* the message field.
|
|
74
|
+
*/
|
|
75
|
+
export async function transportSend(message, config) {
|
|
76
|
+
const serialized = serializeForTransport(message);
|
|
77
|
+
const timeoutMs = config.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
78
|
+
const timeoutSeconds = config.fireAndForget ? 0 : Math.ceil(timeoutMs / 1000);
|
|
79
|
+
const result = await config.callGateway({
|
|
80
|
+
method: 'agent',
|
|
81
|
+
params: {
|
|
82
|
+
agentId: message.to === 'broadcast' ? undefined : message.to,
|
|
83
|
+
message: serialized,
|
|
84
|
+
deliver: false,
|
|
85
|
+
timeoutSeconds,
|
|
86
|
+
label: `fleet:${message.method}`,
|
|
87
|
+
},
|
|
88
|
+
timeoutMs: timeoutMs + 5000,
|
|
89
|
+
});
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Extract a FleetMessage from an incoming hook event's content.
|
|
94
|
+
*
|
|
95
|
+
* Called inside the message_received hook handler to detect and parse
|
|
96
|
+
* fleet messages arriving via OpenClaw's A2A transport.
|
|
97
|
+
*/
|
|
98
|
+
export function extractFleetMessage(hookEvent) {
|
|
99
|
+
const content = hookEvent.content ?? hookEvent.message ?? hookEvent.text;
|
|
100
|
+
if (typeof content !== 'string')
|
|
101
|
+
return null;
|
|
102
|
+
return deserializeFromTransport(content);
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|