@bolloon/bolloon-agent 0.1.1 → 0.1.3
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/bin/bolloon-cli.cjs +165 -0
- package/bin/bolloon-daemon.sh +207 -0
- package/bin/bolloon.cmd +11 -0
- package/dist/agents/constraint-layer.js +10 -15
- package/dist/agents/pi-sdk.js +433 -106
- package/dist/agents/protocol.js +82 -1
- package/dist/agents/subagent-manager.js +2 -2
- package/dist/agents/workflow-engine.js +15 -20
- package/dist/agents/workflow-pivot-loop.js +541 -0
- package/dist/bollharness/src/index.js +5 -0
- package/dist/bollharness/src/scripts/checks/check_adr_plan_numbering.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_api_types.js +45 -0
- package/dist/bollharness/src/scripts/checks/check_artifact_link.js +146 -0
- package/dist/bollharness/src/scripts/checks/check_bridge_deps.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_bugfix_binding.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_bugfix_binding_ci.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_doc_file_references.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_doc_freshness.js +135 -0
- package/dist/bollharness/src/scripts/checks/check_doc_links.js +31 -0
- package/dist/bollharness/src/scripts/checks/check_file_existence_claims.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_fragment_integrity.js +34 -0
- package/dist/bollharness/src/scripts/checks/check_hook_installed.js +63 -0
- package/dist/bollharness/src/scripts/checks/check_issue_closure.js +41 -0
- package/dist/bollharness/src/scripts/checks/check_mcp_parity.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_security.js +48 -0
- package/dist/bollharness/src/scripts/checks/check_skill_parity.js +6 -0
- package/dist/bollharness/src/scripts/checks/check_versions.js +6 -0
- package/dist/bollharness/src/scripts/checks/finding.js +13 -0
- package/dist/bollharness/src/scripts/checks/next_decision_number.js +20 -0
- package/dist/bollharness/src/scripts/checks/regenerate_magic_docs.js +6 -0
- package/dist/bollharness/src/scripts/ci/detect_rebaseline_triggers.js +8 -0
- package/dist/bollharness/src/scripts/ci/scan_subprocess_cfg.js +8 -0
- package/dist/bollharness/src/scripts/ci/scan_verify_artifacts.js +8 -0
- package/dist/bollharness/src/scripts/ci/scan_yaml_schema.js +8 -0
- package/dist/bollharness/src/scripts/context_router.js +67 -0
- package/dist/bollharness/src/scripts/deploy-guard.js +157 -0
- package/dist/bollharness/src/scripts/guard-feedback.js +192 -0
- package/dist/bollharness/src/scripts/guard_router.js +158 -0
- package/dist/bollharness/src/scripts/hooks/_hook_output.js +6 -0
- package/dist/bollharness/src/scripts/hooks/auto-python3.js +6 -0
- package/dist/bollharness/src/scripts/hooks/deploy-progress-on-session-end.js +6 -0
- package/dist/bollharness/src/scripts/hooks/failure-analyzer.js +6 -0
- package/dist/bollharness/src/scripts/hooks/gate-judgment-inject.js +92 -0
- package/dist/bollharness/src/scripts/hooks/gate-transition-judgment.js +63 -0
- package/dist/bollharness/src/scripts/hooks/inbox-ack.js +6 -0
- package/dist/bollharness/src/scripts/hooks/inbox-inject-on-start.js +6 -0
- package/dist/bollharness/src/scripts/hooks/inbox-validate.js +6 -0
- package/dist/bollharness/src/scripts/hooks/inbox-write-ledger.js +6 -0
- package/dist/bollharness/src/scripts/hooks/initializer-agent.js +6 -0
- package/dist/bollharness/src/scripts/hooks/loop-detection.js +73 -0
- package/dist/bollharness/src/scripts/hooks/owner-guard.js +6 -0
- package/dist/bollharness/src/scripts/hooks/precompact.js +6 -0
- package/dist/bollharness/src/scripts/hooks/review-agent-gatekeeper.js +6 -0
- package/dist/bollharness/src/scripts/hooks/risk-tracker.js +108 -0
- package/dist/bollharness/src/scripts/hooks/sanitize-on-read.js +6 -0
- package/dist/bollharness/src/scripts/hooks/session-reflection.js +7 -0
- package/dist/bollharness/src/scripts/hooks/session-start-magic-docs.js +7 -0
- package/dist/bollharness/src/scripts/hooks/session-start-reset-risk.js +7 -0
- package/dist/bollharness/src/scripts/hooks/session-start-toolkit-reminder.js +7 -0
- package/dist/bollharness/src/scripts/hooks/stop-evaluator.js +157 -0
- package/dist/bollharness/src/scripts/hooks/tool-call-counter.js +6 -0
- package/dist/bollharness/src/scripts/hooks/trace-analyzer.js +10 -0
- package/dist/bollharness/src/scripts/install/install-trust-token.js +7 -0
- package/dist/bollharness/src/scripts/install/multi_project_registry.js +9 -0
- package/dist/bollharness/src/scripts/install/phase2_auto.js +21 -0
- package/dist/bollharness/src/scripts/install/pre_commit_installer.js +6 -0
- package/dist/bollharness/src/scripts/install/tier_selector.js +7 -0
- package/dist/bollharness/src/scripts/install/transcript_miner.js +7 -0
- package/dist/bollharness/src/scripts/lib/claim_patterns.js +10 -0
- package/dist/bollharness/src/scripts/lib/sanitize_patterns.js +12 -0
- package/dist/bollharness/src/scripts/sanitize.js +6 -0
- package/dist/bollharness-integration/channel-judgment-engine.js +530 -0
- package/dist/bollharness-integration/context-chain-router.js +383 -0
- package/dist/bollharness-integration/context-router-judgment.js +13 -21
- package/dist/bollharness-integration/context-router.js +22 -64
- package/dist/bollharness-integration/gate-state-machine.js +14 -19
- package/dist/bollharness-integration/gate-transition-hooks.js +16 -61
- package/dist/bollharness-integration/guard-checker.js +21 -68
- package/dist/bollharness-integration/index.js +14 -124
- package/dist/bollharness-integration/integration.js +13 -20
- package/dist/bollharness-integration/llm-judgment-engine.js +569 -0
- package/dist/bollharness-integration/skill-adapter.js +18 -64
- package/dist/cli-entry.js +261 -0
- package/dist/constraint-runtime/src/commands.js +17 -7
- package/dist/constraint-runtime/src/constraint/budget.js +1 -6
- package/dist/constraint-runtime/src/constraint/permission.js +1 -6
- package/dist/constraint-runtime/src/models.js +1 -3
- package/dist/constraint-runtime/src/tools.js +17 -7
- package/dist/constraints/index.js +1 -7
- package/dist/documents/reader.js +8 -49
- package/dist/heartbeat/DaemonManager.js +242 -0
- package/dist/heartbeat/HealthMonitor.js +285 -0
- package/dist/heartbeat/StartupVerifier.js +205 -0
- package/dist/heartbeat/Watchdog.js +168 -0
- package/dist/heartbeat/index.js +84 -0
- package/dist/heartbeat/types.js +5 -0
- package/dist/index.js +381 -28
- package/dist/llm/config-store.js +31 -57
- package/dist/llm/llm-judgment-client.js +389 -0
- package/dist/llm/pi-ai.js +9 -52
- package/dist/network/agent-network.js +46 -90
- package/dist/network/hybrid-messenger.js +125 -0
- package/dist/network/iroh-bootstrap.js +38 -0
- package/dist/network/iroh-discovery.js +145 -0
- package/dist/network/iroh-integration.js +9 -16
- package/dist/network/iroh-transport.js +10 -48
- package/dist/network/p2p.js +23 -62
- package/dist/network/storage/adapters/json-adapter.js +4 -42
- package/dist/network/storage/index.js +147 -0
- package/dist/network/storage/types.js +14 -0
- package/dist/pi-ecosystem/index.js +233 -0
- package/dist/pi-ecosystem-colony/index.js +29 -90
- package/dist/pi-ecosystem-goals/index.js +20 -74
- package/dist/pi-ecosystem-judgment/decision.js +29 -47
- package/dist/pi-ecosystem-judgment/distillation.js +16 -29
- package/dist/pi-ecosystem-judgment/human-value-store.js +13 -60
- package/dist/pi-ecosystem-judgment/index.js +21 -74
- package/dist/pi-ecosystem-judgment/value-injection.js +26 -72
- package/dist/pi-ecosystem-mcp/index.js +24 -78
- package/dist/pi-ecosystem-subagents/index.js +20 -69
- package/dist/social/ant-colony/AdaptiveHeartbeat.js +3 -8
- package/dist/social/ant-colony/PheromoneEngine.js +11 -49
- package/dist/social/ant-colony/index.js +6 -0
- package/dist/social/ant-colony/types.js +4 -8
- package/dist/social/channels/ChannelManager.js +8 -46
- package/dist/social/channels/DiapChannelBridge.js +9 -47
- package/dist/social/channels/InterestMatcher.js +2 -7
- package/dist/social/channels/channel-agent-session.js +309 -0
- package/dist/social/channels/channel-heartbeat-agent.js +494 -0
- package/dist/social/channels/diap-doc-parser.js +204 -0
- package/dist/social/channels/harness-workflow-integrator.js +446 -0
- package/dist/social/channels/index.js +9 -0
- package/dist/social/channels/types.js +3 -7
- package/dist/social/global-shared-context.js +6 -47
- package/dist/social/heartbeat.js +29 -72
- package/dist/social/persona/enhanced-persona.js +299 -0
- package/dist/web/client.js +302 -136
- package/dist/web/components/p2p/index.js +159 -9
- package/dist/web/components/p2p/p2p-connection.js +136 -0
- package/dist/web/components/p2p/p2p-manager.js +24 -0
- package/dist/web/components/p2p/p2p-store-memory.js +1 -1
- package/dist/web/components/p2p/types.js +7 -0
- package/dist/web/index.html +5 -0
- package/dist/web/style.css +118 -0
- package/package.json +12 -6
- package/scripts/build-cli.js +206 -0
- package/scripts/postinstall.js +153 -0
- package/src/agents/pi-sdk.ts +347 -28
- package/src/agents/protocol.ts +95 -1
- package/src/agents/workflow-pivot-loop.ts +674 -0
- package/src/bollharness/CLAUDE.md +73 -0
- package/src/bollharness/README.md +143 -0
- package/src/bollharness/README.zh-CN.md +131 -0
- package/src/bollharness/reference/boll-reference/scripts/hooks/stop-evaluator.md +57 -0
- package/src/bollharness/scripts/context-fragments/artifact-linkage.md +14 -0
- package/src/bollharness/scripts/context-fragments/auth-consumers.md +17 -0
- package/src/bollharness/scripts/context-fragments/bridge-constitution.md +13 -0
- package/src/bollharness/scripts/context-fragments/catalyst-distributed.md +18 -0
- package/src/bollharness/scripts/context-fragments/closure-checklist.md +13 -0
- package/src/bollharness/scripts/context-fragments/contract-consumers.md +15 -0
- package/src/bollharness/scripts/context-fragments/db-shared-structures.md +15 -0
- package/src/bollharness/scripts/context-fragments/fixed-three-layers.md +19 -0
- package/src/bollharness/scripts/context-fragments/general-dev-principles.md +11 -0
- package/src/bollharness/scripts/context-fragments/issue-first.md +8 -0
- package/src/bollharness/scripts/context-fragments/mcp-parity.md +16 -0
- package/src/bollharness/scripts/context-fragments/pi-agent-operations.md +108 -0
- package/src/bollharness/scripts/context-fragments/protocol-consumers.md +15 -0
- package/src/bollharness/scripts/context-fragments/run-events-consumers.md +15 -0
- package/src/bollharness/scripts/context-fragments/scene-fidelity.md +13 -0
- package/src/bollharness/scripts/context-fragments/truth-source-hierarchy.md +15 -0
- package/src/bollharness/scripts/context-fragments/two-language.md +15 -0
- package/src/bollharness/scripts/context-fragments/version-sources.md +14 -0
- package/src/bollharness/scripts/hooks/stop-evaluator.md +83 -0
- package/src/bollharness/templates/scaffold/CLAUDE.md +89 -0
- package/src/cli-entry.ts +304 -0
- package/src/heartbeat/DaemonManager.ts +283 -0
- package/src/heartbeat/HealthMonitor.ts +316 -0
- package/src/heartbeat/StartupVerifier.ts +223 -0
- package/src/heartbeat/Watchdog.ts +198 -0
- package/src/heartbeat/index.ts +108 -0
- package/src/heartbeat/types.ts +82 -0
- package/src/llm/config-store.ts +23 -5
- package/src/network/iroh-transport.ts +3 -3
- package/src/web/client.js +302 -136
- package/src/web/components/p2p/P2PModal.tsx +91 -3
- package/src/web/components/p2p/index.ts +171 -9
- package/src/web/components/p2p/p2p-connection.ts +153 -1
- package/src/web/components/p2p/p2p-manager.ts +39 -1
- package/src/web/components/p2p/p2p-store-memory.ts +1 -1
- package/src/web/components/p2p/p2p-tools.ts +315 -0
- package/src/web/components/p2p/types.ts +58 -0
- package/src/web/design.md +99 -0
- package/src/web/index.html +5 -0
- package/src/web/server.ts +353 -36
- package/src/web/style.css +118 -0
- package/tsconfig.cli.json +16 -0
- package/tsconfig.electron.json +1 -1
- package/tsconfig.json +1 -2
- package/dist/web/server.js +0 -1647
- package/dist/web/server.js.map +0 -1
|
@@ -1,43 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.irohTransport = exports.IrohTransport = void 0;
|
|
37
|
-
const iroh_1 = require("@rayhanadev/iroh");
|
|
38
|
-
const crypto = __importStar(require("crypto"));
|
|
1
|
+
import { Endpoint } from '@rayhanadev/iroh';
|
|
2
|
+
import * as crypto from 'crypto';
|
|
39
3
|
const IROH_ALPN = 'bolloon/iroh/1';
|
|
40
|
-
class IrohTransport {
|
|
4
|
+
export class IrohTransport {
|
|
41
5
|
endpoint = null;
|
|
42
6
|
messageHandlers = new Map();
|
|
43
7
|
running = false;
|
|
@@ -53,18 +17,18 @@ class IrohTransport {
|
|
|
53
17
|
pendingRequests = new Map();
|
|
54
18
|
requestIdToNodeId = new Map();
|
|
55
19
|
async start(secretKey, enablePersistence = false) {
|
|
56
|
-
if (this.endpoint) {
|
|
20
|
+
if (this.endpoint && this.ownNodeId) {
|
|
57
21
|
// 已启动,返回当前信息
|
|
58
22
|
return {
|
|
59
23
|
nodeId: this.ownNodeId,
|
|
60
|
-
addr: this.
|
|
24
|
+
addr: this.ownNodeId // iroh 没有 listenAddresses,用 nodeId 作为 addr
|
|
61
25
|
};
|
|
62
26
|
}
|
|
63
27
|
const options = { alpns: [IROH_ALPN] };
|
|
64
28
|
if (secretKey) {
|
|
65
29
|
options.secretKey = secretKey;
|
|
66
30
|
}
|
|
67
|
-
this.endpoint = await
|
|
31
|
+
this.endpoint = await Endpoint.createWithOptions(options);
|
|
68
32
|
this.ownNodeId = this.endpoint.nodeId();
|
|
69
33
|
await this.endpoint.online();
|
|
70
34
|
this.running = true;
|
|
@@ -79,14 +43,14 @@ class IrohTransport {
|
|
|
79
43
|
this.startAcceptLoop();
|
|
80
44
|
return {
|
|
81
45
|
nodeId: this.endpoint.nodeId(),
|
|
82
|
-
addr: this.
|
|
46
|
+
addr: this.ownNodeId // iroh 没有 addr(),用 nodeId
|
|
83
47
|
};
|
|
84
48
|
}
|
|
85
49
|
async createMessageStore() {
|
|
86
50
|
// 动态导入 JSON 存储适配器
|
|
87
51
|
try {
|
|
88
|
-
const { JsonMessageStore } = await
|
|
89
|
-
const path = await
|
|
52
|
+
const { JsonMessageStore } = await import('./storage/adapters/json-adapter.js');
|
|
53
|
+
const path = await import('path');
|
|
90
54
|
const baseDir = path.join(process.env.HOME || '/tmp', '.bolloon', 'messages-iroh');
|
|
91
55
|
return new JsonMessageStore({ baseDir });
|
|
92
56
|
}
|
|
@@ -501,6 +465,4 @@ class IrohTransport {
|
|
|
501
465
|
console.log('[IrohTransport] Shut down');
|
|
502
466
|
}
|
|
503
467
|
}
|
|
504
|
-
|
|
505
|
-
exports.irohTransport = new IrohTransport();
|
|
506
|
-
//# sourceMappingURL=iroh-transport.js.map
|
|
468
|
+
export const irohTransport = new IrohTransport();
|
package/dist/network/p2p.js
CHANGED
|
@@ -1,51 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.p2pNetwork = exports.P2PNetwork = exports.RequestResponseManager = void 0;
|
|
37
|
-
const libp2p_1 = require("libp2p");
|
|
38
|
-
const tcp_1 = require("@libp2p/tcp");
|
|
39
|
-
const multiaddr_1 = require("@multiformats/multiaddr");
|
|
40
|
-
const circuit_relay_v2_1 = require("@libp2p/circuit-relay-v2");
|
|
41
|
-
const autonat_1 = require("@libp2p/autonat");
|
|
42
|
-
const upnp_nat_1 = require("@libp2p/upnp-nat");
|
|
43
|
-
const fs = __importStar(require("fs/promises"));
|
|
44
|
-
const path = __importStar(require("path"));
|
|
1
|
+
import { createLibp2p } from 'libp2p';
|
|
2
|
+
import { tcp } from '@libp2p/tcp';
|
|
3
|
+
import { multiaddr as createMultiaddr } from '@multiformats/multiaddr';
|
|
4
|
+
import { circuitRelayTransport } from '@libp2p/circuit-relay-v2';
|
|
5
|
+
import { autoNAT } from '@libp2p/autonat';
|
|
6
|
+
import { uPnPNAT } from '@libp2p/upnp-nat';
|
|
7
|
+
import * as fs from 'fs/promises';
|
|
8
|
+
import * as path from 'path';
|
|
45
9
|
const PEER_STORE_PATH = path.join(process.env.HOME || '/tmp', '.bolloon', 'peer-store.json');
|
|
46
10
|
const RECONNECT_DELAY_MS = 5000;
|
|
47
11
|
const MAX_RECONNECT_ATTEMPTS = 3;
|
|
48
|
-
class RequestResponseManager {
|
|
12
|
+
export class RequestResponseManager {
|
|
49
13
|
pendingRequests = new Map();
|
|
50
14
|
responseHandlers = new Map();
|
|
51
15
|
requestTimeoutMs = 30000;
|
|
@@ -120,8 +84,7 @@ class RequestResponseManager {
|
|
|
120
84
|
this.pendingRequests.clear();
|
|
121
85
|
}
|
|
122
86
|
}
|
|
123
|
-
|
|
124
|
-
class P2PNetwork {
|
|
87
|
+
export class P2PNetwork {
|
|
125
88
|
node = null;
|
|
126
89
|
messageHandlers = new Map();
|
|
127
90
|
offlineMessages = new Map();
|
|
@@ -143,7 +106,7 @@ class P2PNetwork {
|
|
|
143
106
|
}
|
|
144
107
|
async enablePersistence() {
|
|
145
108
|
try {
|
|
146
|
-
const { JsonMessageStore } = await
|
|
109
|
+
const { JsonMessageStore } = await import('./storage/adapters/json-adapter.js');
|
|
147
110
|
const baseDir = path.join(process.env.HOME || '/tmp', '.bolloon', 'messages-libp2p');
|
|
148
111
|
this.messageStore = new JsonMessageStore({ baseDir });
|
|
149
112
|
await this.messageStore.initialize();
|
|
@@ -187,7 +150,7 @@ class P2PNetwork {
|
|
|
187
150
|
const data = typeof payload === 'string'
|
|
188
151
|
? new TextEncoder().encode(`${type}:${payload}`)
|
|
189
152
|
: payload;
|
|
190
|
-
const ma = (
|
|
153
|
+
const ma = createMultiaddr(`/p2p/${peerId}`);
|
|
191
154
|
const { stream } = await this.node.dialProtocol(ma, '/agent/message');
|
|
192
155
|
stream.send(data);
|
|
193
156
|
return true;
|
|
@@ -201,11 +164,11 @@ class P2PNetwork {
|
|
|
201
164
|
const enableRelay = config?.enableRelay ?? true;
|
|
202
165
|
const enableAutoNat = config?.enableAutoNat ?? true;
|
|
203
166
|
const enableUPnP = config?.enableUPnP ?? true;
|
|
204
|
-
const transports = [
|
|
167
|
+
const transports = [tcp()];
|
|
205
168
|
const services = {};
|
|
206
169
|
if (enableRelay) {
|
|
207
170
|
try {
|
|
208
|
-
const relayTransport =
|
|
171
|
+
const relayTransport = circuitRelayTransport();
|
|
209
172
|
transports.push(relayTransport);
|
|
210
173
|
}
|
|
211
174
|
catch (e) {
|
|
@@ -214,7 +177,7 @@ class P2PNetwork {
|
|
|
214
177
|
}
|
|
215
178
|
if (enableAutoNat) {
|
|
216
179
|
try {
|
|
217
|
-
services.autonat =
|
|
180
|
+
services.autonat = autoNAT();
|
|
218
181
|
}
|
|
219
182
|
catch (e) {
|
|
220
183
|
console.warn(`[P2P] Failed to setup AutoNAT:`, e);
|
|
@@ -222,13 +185,13 @@ class P2PNetwork {
|
|
|
222
185
|
}
|
|
223
186
|
if (enableUPnP) {
|
|
224
187
|
try {
|
|
225
|
-
services.upnpNAT =
|
|
188
|
+
services.upnpNAT = uPnPNAT();
|
|
226
189
|
}
|
|
227
190
|
catch (e) {
|
|
228
191
|
console.warn(`[P2P] Failed to setup UPnP:`, e);
|
|
229
192
|
}
|
|
230
193
|
}
|
|
231
|
-
this.node = await
|
|
194
|
+
this.node = await createLibp2p({
|
|
232
195
|
addresses: {
|
|
233
196
|
listen: ['/ip4/0.0.0.0/tcp/0']
|
|
234
197
|
},
|
|
@@ -247,7 +210,7 @@ class P2PNetwork {
|
|
|
247
210
|
if (config?.relayPeers && config.relayPeers.length > 0) {
|
|
248
211
|
for (const relayAddr of config.relayPeers) {
|
|
249
212
|
try {
|
|
250
|
-
const ma = (
|
|
213
|
+
const ma = createMultiaddr(relayAddr);
|
|
251
214
|
await this.node.dial(ma);
|
|
252
215
|
console.log(`[P2P] Connected to relay peer: ${relayAddr}`);
|
|
253
216
|
}
|
|
@@ -324,7 +287,7 @@ class P2PNetwork {
|
|
|
324
287
|
if (!this.node)
|
|
325
288
|
return false;
|
|
326
289
|
try {
|
|
327
|
-
const ma = (
|
|
290
|
+
const ma = createMultiaddr(`${relayAddr}/p2p/${targetPeerId}`);
|
|
328
291
|
await this.node.dial(ma);
|
|
329
292
|
console.log(`[P2P] Dialed ${targetPeerId} via relay ${relayAddr}`);
|
|
330
293
|
return true;
|
|
@@ -396,7 +359,7 @@ class P2PNetwork {
|
|
|
396
359
|
console.log(`[P2P] Reconnecting to ${peerId} (attempt ${attempt + 1})...`);
|
|
397
360
|
for (const addr of peerInfo.multiaddrs) {
|
|
398
361
|
try {
|
|
399
|
-
const ma = (
|
|
362
|
+
const ma = createMultiaddr(addr);
|
|
400
363
|
await this.node.dial(ma);
|
|
401
364
|
peerInfo.lastConnected = Date.now();
|
|
402
365
|
peerInfo.lastAttempt = undefined;
|
|
@@ -440,7 +403,7 @@ class P2PNetwork {
|
|
|
440
403
|
return;
|
|
441
404
|
for (const addr of peers) {
|
|
442
405
|
try {
|
|
443
|
-
const ma = (
|
|
406
|
+
const ma = createMultiaddr(addr);
|
|
444
407
|
await this.node.dial(ma);
|
|
445
408
|
console.log(`[P2P] Connected to bootstrap peer: ${addr}`);
|
|
446
409
|
const peerId = ma.getPeerId?.() || ma.peerId;
|
|
@@ -609,7 +572,7 @@ class P2PNetwork {
|
|
|
609
572
|
async sendRawMessage(peerId, data) {
|
|
610
573
|
if (!this.node)
|
|
611
574
|
throw new Error('Node not initialized');
|
|
612
|
-
const ma = (
|
|
575
|
+
const ma = createMultiaddr(`/p2p/${peerId}`);
|
|
613
576
|
const { stream } = await this.node.dialProtocol(ma, '/agent/message');
|
|
614
577
|
stream.send(data);
|
|
615
578
|
}
|
|
@@ -859,6 +822,4 @@ class P2PNetwork {
|
|
|
859
822
|
return this.messageStore.getPendingOfflineCount();
|
|
860
823
|
}
|
|
861
824
|
}
|
|
862
|
-
|
|
863
|
-
exports.p2pNetwork = new P2PNetwork();
|
|
864
|
-
//# sourceMappingURL=p2p.js.map
|
|
825
|
+
export const p2pNetwork = new P2PNetwork();
|
|
@@ -1,46 +1,10 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* JSON File Adapter for MessageStore
|
|
4
3
|
* 基于 JSON 文件的消息存储实现
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
-
}
|
|
12
|
-
Object.defineProperty(o, k2, desc);
|
|
13
|
-
}) : (function(o, m, k, k2) {
|
|
14
|
-
if (k2 === undefined) k2 = k;
|
|
15
|
-
o[k2] = m[k];
|
|
16
|
-
}));
|
|
17
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
-
}) : function(o, v) {
|
|
20
|
-
o["default"] = v;
|
|
21
|
-
});
|
|
22
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
-
var ownKeys = function(o) {
|
|
24
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
-
var ar = [];
|
|
26
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
-
return ar;
|
|
28
|
-
};
|
|
29
|
-
return ownKeys(o);
|
|
30
|
-
};
|
|
31
|
-
return function (mod) {
|
|
32
|
-
if (mod && mod.__esModule) return mod;
|
|
33
|
-
var result = {};
|
|
34
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
-
__setModuleDefault(result, mod);
|
|
36
|
-
return result;
|
|
37
|
-
};
|
|
38
|
-
})();
|
|
39
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
-
exports.JsonMessageStore = void 0;
|
|
41
|
-
const fs = __importStar(require("fs/promises"));
|
|
42
|
-
const path = __importStar(require("path"));
|
|
43
|
-
const crypto = __importStar(require("crypto"));
|
|
5
|
+
import * as fs from 'fs/promises';
|
|
6
|
+
import * as path from 'path';
|
|
7
|
+
import * as crypto from 'crypto';
|
|
44
8
|
const DEFAULT_CONFIG = {
|
|
45
9
|
baseDir: '',
|
|
46
10
|
maxFileSize: 10 * 1024 * 1024, // 10MB
|
|
@@ -48,7 +12,7 @@ const DEFAULT_CONFIG = {
|
|
|
48
12
|
fileNamingStrategy: 'daily',
|
|
49
13
|
maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
|
|
50
14
|
};
|
|
51
|
-
class JsonMessageStore {
|
|
15
|
+
export class JsonMessageStore {
|
|
52
16
|
config;
|
|
53
17
|
initialized = false;
|
|
54
18
|
offlineMessages = new Map();
|
|
@@ -397,5 +361,3 @@ class JsonMessageStore {
|
|
|
397
361
|
}
|
|
398
362
|
}
|
|
399
363
|
}
|
|
400
|
-
exports.JsonMessageStore = JsonMessageStore;
|
|
401
|
-
//# sourceMappingURL=json-adapter.js.map
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage Layer Entry Point
|
|
3
|
+
* 导出消息存储工厂函数和类型
|
|
4
|
+
*/
|
|
5
|
+
export { DEFAULT_STORAGE_CONFIG } from './types.js';
|
|
6
|
+
import { JsonMessageStore } from './adapters/json-adapter.js';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
// 默认存储配置
|
|
9
|
+
const DEFAULT_BASE_DIR = path.join(process.env.HOME || '/tmp', '.bolloon', 'messages');
|
|
10
|
+
/**
|
|
11
|
+
* 创建消息存储实例
|
|
12
|
+
* @param transport 传输类型 ('iroh' | 'libp2p')
|
|
13
|
+
* @param config 存储配置
|
|
14
|
+
* @returns MessageStore 实例
|
|
15
|
+
*/
|
|
16
|
+
export async function createMessageStore(transport = 'libp2p', config) {
|
|
17
|
+
const fullConfig = {
|
|
18
|
+
baseDir: config?.baseDir || DEFAULT_BASE_DIR,
|
|
19
|
+
maxFileSize: config?.maxFileSize || 10 * 1024 * 1024,
|
|
20
|
+
maxMessagesPerFile: config?.maxMessagesPerFile || 1000,
|
|
21
|
+
fileNamingStrategy: config?.fileNamingStrategy || 'daily',
|
|
22
|
+
maxAge: config?.maxAge || 30 * 24 * 60 * 60 * 1000,
|
|
23
|
+
};
|
|
24
|
+
const store = new JsonMessageStore(fullConfig);
|
|
25
|
+
await store.initialize();
|
|
26
|
+
console.log(`[Storage] Created ${transport} message store at ${fullConfig.baseDir}`);
|
|
27
|
+
return store;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 创建离线消息存储(无持久化,仅内存)
|
|
31
|
+
* 用于不需要消息历史的轻量级场景
|
|
32
|
+
*/
|
|
33
|
+
export function createInMemoryStore() {
|
|
34
|
+
const messages = new Map();
|
|
35
|
+
const offlineQueues = new Map();
|
|
36
|
+
const pendingResponses = new Map();
|
|
37
|
+
return {
|
|
38
|
+
async saveMessage(msg) {
|
|
39
|
+
const id = crypto.randomUUID();
|
|
40
|
+
const stored = { ...msg, id };
|
|
41
|
+
messages.set(id, stored);
|
|
42
|
+
return stored;
|
|
43
|
+
},
|
|
44
|
+
async getMessage(id) {
|
|
45
|
+
return messages.get(id) || null;
|
|
46
|
+
},
|
|
47
|
+
async updateMessageStatus(id, status) {
|
|
48
|
+
const msg = messages.get(id);
|
|
49
|
+
if (msg) {
|
|
50
|
+
msg.status = status;
|
|
51
|
+
messages.set(id, msg);
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
async getMessages(options) {
|
|
55
|
+
let result = Array.from(messages.values());
|
|
56
|
+
if (options?.direction)
|
|
57
|
+
result = result.filter(m => m.direction === options.direction);
|
|
58
|
+
if (options?.type)
|
|
59
|
+
result = result.filter(m => m.type === options.type);
|
|
60
|
+
if (options?.from)
|
|
61
|
+
result = result.filter(m => m.from === options.from);
|
|
62
|
+
if (options?.to)
|
|
63
|
+
result = result.filter(m => m.to === options.to);
|
|
64
|
+
if (options?.startTime)
|
|
65
|
+
result = result.filter(m => m.timestamp >= options.startTime);
|
|
66
|
+
if (options?.endTime)
|
|
67
|
+
result = result.filter(m => m.timestamp <= options.endTime);
|
|
68
|
+
if (options?.status)
|
|
69
|
+
result = result.filter(m => m.status === options.status);
|
|
70
|
+
result.sort((a, b) => b.timestamp - a.timestamp);
|
|
71
|
+
if (options?.offset)
|
|
72
|
+
result = result.slice(options.offset);
|
|
73
|
+
if (options?.limit)
|
|
74
|
+
result = result.slice(0, options.limit);
|
|
75
|
+
return result;
|
|
76
|
+
},
|
|
77
|
+
async deleteMessage(id) {
|
|
78
|
+
messages.delete(id);
|
|
79
|
+
},
|
|
80
|
+
async enqueueOfflineMessage(msg) {
|
|
81
|
+
const id = crypto.randomUUID();
|
|
82
|
+
const offline = { ...msg, id };
|
|
83
|
+
const queue = offlineQueues.get(msg.targetNodeId) || [];
|
|
84
|
+
queue.push(offline);
|
|
85
|
+
offlineQueues.set(msg.targetNodeId, queue);
|
|
86
|
+
return offline;
|
|
87
|
+
},
|
|
88
|
+
async getOfflineMessages(targetNodeId) {
|
|
89
|
+
return offlineQueues.get(targetNodeId) || [];
|
|
90
|
+
},
|
|
91
|
+
async dequeueOfflineMessage(id) {
|
|
92
|
+
for (const [nodeId, queue] of offlineQueues.entries()) {
|
|
93
|
+
const idx = queue.findIndex(m => m.id === id);
|
|
94
|
+
if (idx >= 0) {
|
|
95
|
+
queue.splice(idx, 1);
|
|
96
|
+
offlineQueues.set(nodeId, queue);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
async incrementOfflineRetry(id) {
|
|
102
|
+
for (const queue of offlineQueues.values()) {
|
|
103
|
+
const msg = queue.find(m => m.id === id);
|
|
104
|
+
if (msg) {
|
|
105
|
+
msg.retryCount++;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
async getPendingOfflineCount() {
|
|
111
|
+
let count = 0;
|
|
112
|
+
for (const queue of offlineQueues.values()) {
|
|
113
|
+
count += queue.length;
|
|
114
|
+
}
|
|
115
|
+
return count;
|
|
116
|
+
},
|
|
117
|
+
async savePendingResponse(req) {
|
|
118
|
+
const id = crypto.randomUUID();
|
|
119
|
+
const pending = { ...req, id };
|
|
120
|
+
pendingResponses.set(req.requestId, pending);
|
|
121
|
+
return pending;
|
|
122
|
+
},
|
|
123
|
+
async getPendingResponse(requestId) {
|
|
124
|
+
return pendingResponses.get(requestId) || null;
|
|
125
|
+
},
|
|
126
|
+
async removePendingResponse(requestId) {
|
|
127
|
+
pendingResponses.delete(requestId);
|
|
128
|
+
},
|
|
129
|
+
async getMessageCount() {
|
|
130
|
+
return messages.size;
|
|
131
|
+
},
|
|
132
|
+
async getOfflineMessageCount() {
|
|
133
|
+
return this.getPendingOfflineCount();
|
|
134
|
+
},
|
|
135
|
+
async pruneOldMessages() {
|
|
136
|
+
return 0;
|
|
137
|
+
},
|
|
138
|
+
async initialize() { },
|
|
139
|
+
async shutdown() {
|
|
140
|
+
messages.clear();
|
|
141
|
+
offlineQueues.clear();
|
|
142
|
+
pendingResponses.clear();
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
// 导入 crypto 用于内存存储的 ID 生成
|
|
147
|
+
import * as crypto from 'crypto';
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Storage Layer Type Definitions
|
|
3
|
+
* 消息持久化和离线消息队列的类型定义
|
|
4
|
+
*/
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// 导出默认配置
|
|
7
|
+
// ============================================================================
|
|
8
|
+
export const DEFAULT_STORAGE_CONFIG = {
|
|
9
|
+
baseDir: '',
|
|
10
|
+
maxFileSize: 10 * 1024 * 1024, // 10MB
|
|
11
|
+
maxMessagesPerFile: 1000,
|
|
12
|
+
fileNamingStrategy: 'daily',
|
|
13
|
+
maxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
|
|
14
|
+
};
|