network-ai 5.10.2 → 5.11.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 +2 -2
- package/README.md +5 -3
- package/SKILL.md +3 -3
- package/dist/esm/adapters/a2a-adapter.js +235 -0
- package/dist/esm/adapters/a2a-adapter.js.map +1 -0
- package/dist/esm/adapters/adapter-registry.js +613 -0
- package/dist/esm/adapters/adapter-registry.js.map +1 -0
- package/dist/esm/adapters/agno-adapter.js +140 -0
- package/dist/esm/adapters/agno-adapter.js.map +1 -0
- package/dist/esm/adapters/anthropic-computer-use-adapter.js +180 -0
- package/dist/esm/adapters/anthropic-computer-use-adapter.js.map +1 -0
- package/dist/esm/adapters/aps-adapter.js +289 -0
- package/dist/esm/adapters/aps-adapter.js.map +1 -0
- package/dist/esm/adapters/autogen-adapter.js +141 -0
- package/dist/esm/adapters/autogen-adapter.js.map +1 -0
- package/dist/esm/adapters/base-adapter.js +104 -0
- package/dist/esm/adapters/base-adapter.js.map +1 -0
- package/dist/esm/adapters/browser-agent-adapter.js +219 -0
- package/dist/esm/adapters/browser-agent-adapter.js.map +1 -0
- package/dist/esm/adapters/codex-adapter.js +318 -0
- package/dist/esm/adapters/codex-adapter.js.map +1 -0
- package/dist/esm/adapters/copilot-adapter.js +132 -0
- package/dist/esm/adapters/copilot-adapter.js.map +1 -0
- package/dist/esm/adapters/crewai-adapter.js +148 -0
- package/dist/esm/adapters/crewai-adapter.js.map +1 -0
- package/dist/esm/adapters/custom-adapter.js +142 -0
- package/dist/esm/adapters/custom-adapter.js.map +1 -0
- package/dist/esm/adapters/custom-streaming-adapter.js +181 -0
- package/dist/esm/adapters/custom-streaming-adapter.js.map +1 -0
- package/dist/esm/adapters/dspy-adapter.js +127 -0
- package/dist/esm/adapters/dspy-adapter.js.map +1 -0
- package/dist/esm/adapters/haystack-adapter.js +149 -0
- package/dist/esm/adapters/haystack-adapter.js.map +1 -0
- package/dist/esm/adapters/hermes-adapter.js +217 -0
- package/dist/esm/adapters/hermes-adapter.js.map +1 -0
- package/dist/esm/adapters/index.js +109 -0
- package/dist/esm/adapters/index.js.map +1 -0
- package/dist/esm/adapters/langchain-adapter.js +134 -0
- package/dist/esm/adapters/langchain-adapter.js.map +1 -0
- package/dist/esm/adapters/langchain-streaming-adapter.js +161 -0
- package/dist/esm/adapters/langchain-streaming-adapter.js.map +1 -0
- package/dist/esm/adapters/langgraph-adapter.js +119 -0
- package/dist/esm/adapters/langgraph-adapter.js.map +1 -0
- package/dist/esm/adapters/llamaindex-adapter.js +135 -0
- package/dist/esm/adapters/llamaindex-adapter.js.map +1 -0
- package/dist/esm/adapters/mcp-adapter.js +200 -0
- package/dist/esm/adapters/mcp-adapter.js.map +1 -0
- package/dist/esm/adapters/minimax-adapter.js +233 -0
- package/dist/esm/adapters/minimax-adapter.js.map +1 -0
- package/dist/esm/adapters/nemoclaw-adapter.js +465 -0
- package/dist/esm/adapters/nemoclaw-adapter.js.map +1 -0
- package/dist/esm/adapters/openai-agents-adapter.js +118 -0
- package/dist/esm/adapters/openai-agents-adapter.js.map +1 -0
- package/dist/esm/adapters/openai-assistants-adapter.js +130 -0
- package/dist/esm/adapters/openai-assistants-adapter.js.map +1 -0
- package/dist/esm/adapters/openclaw-adapter.js +107 -0
- package/dist/esm/adapters/openclaw-adapter.js.map +1 -0
- package/dist/esm/adapters/orchestrator-adapter.js +218 -0
- package/dist/esm/adapters/orchestrator-adapter.js.map +1 -0
- package/dist/esm/adapters/pydantic-ai-adapter.js +163 -0
- package/dist/esm/adapters/pydantic-ai-adapter.js.map +1 -0
- package/dist/esm/adapters/rlm-adapter.js +167 -0
- package/dist/esm/adapters/rlm-adapter.js.map +1 -0
- package/dist/esm/adapters/semantic-kernel-adapter.js +123 -0
- package/dist/esm/adapters/semantic-kernel-adapter.js.map +1 -0
- package/dist/esm/adapters/streaming-base-adapter.js +74 -0
- package/dist/esm/adapters/streaming-base-adapter.js.map +1 -0
- package/dist/esm/adapters/vertex-ai-adapter.js +166 -0
- package/dist/esm/adapters/vertex-ai-adapter.js.map +1 -0
- package/dist/esm/demo-control-plane.js +147 -0
- package/dist/esm/demo-control-plane.js.map +1 -0
- package/dist/esm/demo-worktree-dashboard.js +131 -0
- package/dist/esm/demo-worktree-dashboard.js.map +1 -0
- package/dist/esm/examples/01-hello-swarm.js +165 -0
- package/dist/esm/examples/01-hello-swarm.js.map +1 -0
- package/dist/esm/examples/02-fsm-pipeline.js +189 -0
- package/dist/esm/examples/02-fsm-pipeline.js.map +1 -0
- package/dist/esm/examples/03-parallel-agents.js +192 -0
- package/dist/esm/examples/03-parallel-agents.js.map +1 -0
- package/dist/esm/examples/05-code-review-swarm.js +1177 -0
- package/dist/esm/examples/05-code-review-swarm.js.map +1 -0
- package/dist/esm/examples/06-ai-pipeline-demo.js +263 -0
- package/dist/esm/examples/06-ai-pipeline-demo.js.map +1 -0
- package/dist/esm/examples/07-full-showcase.js +946 -0
- package/dist/esm/examples/07-full-showcase.js.map +1 -0
- package/dist/esm/examples/08-control-plane-stress-demo.js +186 -0
- package/dist/esm/examples/08-control-plane-stress-demo.js.map +1 -0
- package/dist/esm/examples/09-real-langchain.js +231 -0
- package/dist/esm/examples/09-real-langchain.js.map +1 -0
- package/dist/esm/examples/10-nemoclaw-sandbox-swarm.js +270 -0
- package/dist/esm/examples/10-nemoclaw-sandbox-swarm.js.map +1 -0
- package/dist/esm/examples/demo-runner.js +119 -0
- package/dist/esm/examples/demo-runner.js.map +1 -0
- package/dist/esm/index.js +1352 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lib/adapter-hooks.js +216 -0
- package/dist/esm/lib/adapter-hooks.js.map +1 -0
- package/dist/esm/lib/adapter-test-harness.js +118 -0
- package/dist/esm/lib/adapter-test-harness.js.map +1 -0
- package/dist/esm/lib/agent-conversation.js +155 -0
- package/dist/esm/lib/agent-conversation.js.map +1 -0
- package/dist/esm/lib/agent-debate.js +146 -0
- package/dist/esm/lib/agent-debate.js.map +1 -0
- package/dist/esm/lib/agent-memory.js +336 -0
- package/dist/esm/lib/agent-memory.js.map +1 -0
- package/dist/esm/lib/agent-runtime.js +818 -0
- package/dist/esm/lib/agent-runtime.js.map +1 -0
- package/dist/esm/lib/agent-vcr.js +218 -0
- package/dist/esm/lib/agent-vcr.js.map +1 -0
- package/dist/esm/lib/anomaly-detector.js +178 -0
- package/dist/esm/lib/anomaly-detector.js.map +1 -0
- package/dist/esm/lib/approval-inbox.js +385 -0
- package/dist/esm/lib/approval-inbox.js.map +1 -0
- package/dist/esm/lib/auth-guardian.js +692 -0
- package/dist/esm/lib/auth-guardian.js.map +1 -0
- package/dist/esm/lib/auth-validator.js +32 -0
- package/dist/esm/lib/auth-validator.js.map +1 -0
- package/dist/esm/lib/blackboard-backend-crdt.js +251 -0
- package/dist/esm/lib/blackboard-backend-crdt.js.map +1 -0
- package/dist/esm/lib/blackboard-backend-redis.js +244 -0
- package/dist/esm/lib/blackboard-backend-redis.js.map +1 -0
- package/dist/esm/lib/blackboard-backend.js +141 -0
- package/dist/esm/lib/blackboard-backend.js.map +1 -0
- package/dist/esm/lib/blackboard-validator.js +985 -0
- package/dist/esm/lib/blackboard-validator.js.map +1 -0
- package/dist/esm/lib/circuit-breaker.js +164 -0
- package/dist/esm/lib/circuit-breaker.js.map +1 -0
- package/dist/esm/lib/claim-verifier.js +173 -0
- package/dist/esm/lib/claim-verifier.js.map +1 -0
- package/dist/esm/lib/comparison-runner.js +138 -0
- package/dist/esm/lib/comparison-runner.js.map +1 -0
- package/dist/esm/lib/compliance-monitor.js +261 -0
- package/dist/esm/lib/compliance-monitor.js.map +1 -0
- package/dist/esm/lib/confidence-filter.js +210 -0
- package/dist/esm/lib/confidence-filter.js.map +1 -0
- package/dist/esm/lib/config-watcher.js +215 -0
- package/dist/esm/lib/config-watcher.js.map +1 -0
- package/dist/esm/lib/consistency.js +274 -0
- package/dist/esm/lib/consistency.js.map +1 -0
- package/dist/esm/lib/console-ui.js +276 -0
- package/dist/esm/lib/console-ui.js.map +1 -0
- package/dist/esm/lib/context-throttler.js +171 -0
- package/dist/esm/lib/context-throttler.js.map +1 -0
- package/dist/esm/lib/control-plane.js +527 -0
- package/dist/esm/lib/control-plane.js.map +1 -0
- package/dist/esm/lib/cost-governor.js +128 -0
- package/dist/esm/lib/cost-governor.js.map +1 -0
- package/dist/esm/lib/cost-heatmap.js +161 -0
- package/dist/esm/lib/cost-heatmap.js.map +1 -0
- package/dist/esm/lib/coverage-gate.js +213 -0
- package/dist/esm/lib/coverage-gate.js.map +1 -0
- package/dist/esm/lib/coverage-reporter.js +177 -0
- package/dist/esm/lib/coverage-reporter.js.map +1 -0
- package/dist/esm/lib/crdt.js +141 -0
- package/dist/esm/lib/crdt.js.map +1 -0
- package/dist/esm/lib/dashboard-server.js +403 -0
- package/dist/esm/lib/dashboard-server.js.map +1 -0
- package/dist/esm/lib/dry-run.js +130 -0
- package/dist/esm/lib/dry-run.js.map +1 -0
- package/dist/esm/lib/env-manager.js +518 -0
- package/dist/esm/lib/env-manager.js.map +1 -0
- package/dist/esm/lib/errors.js +201 -0
- package/dist/esm/lib/errors.js.map +1 -0
- package/dist/esm/lib/event-bus.js +229 -0
- package/dist/esm/lib/event-bus.js.map +1 -0
- package/dist/esm/lib/explainability.js +102 -0
- package/dist/esm/lib/explainability.js.map +1 -0
- package/dist/esm/lib/fan-out.js +237 -0
- package/dist/esm/lib/fan-out.js.map +1 -0
- package/dist/esm/lib/federated-budget.js +322 -0
- package/dist/esm/lib/federated-budget.js.map +1 -0
- package/dist/esm/lib/fsm-journey.js +478 -0
- package/dist/esm/lib/fsm-journey.js.map +1 -0
- package/dist/esm/lib/goal-decomposer.js +698 -0
- package/dist/esm/lib/goal-decomposer.js.map +1 -0
- package/dist/esm/lib/goal-dsl.js +391 -0
- package/dist/esm/lib/goal-dsl.js.map +1 -0
- package/dist/esm/lib/job-queue.js +310 -0
- package/dist/esm/lib/job-queue.js.map +1 -0
- package/dist/esm/lib/landscape-agent.js +134 -0
- package/dist/esm/lib/landscape-agent.js.map +1 -0
- package/dist/esm/lib/learning-loop.js +181 -0
- package/dist/esm/lib/learning-loop.js.map +1 -0
- package/dist/esm/lib/lifecycle-hooks.js +148 -0
- package/dist/esm/lib/lifecycle-hooks.js.map +1 -0
- package/dist/esm/lib/locked-blackboard.js +1295 -0
- package/dist/esm/lib/locked-blackboard.js.map +1 -0
- package/dist/esm/lib/logger.js +150 -0
- package/dist/esm/lib/logger.js.map +1 -0
- package/dist/esm/lib/mcp-blackboard-tools.js +298 -0
- package/dist/esm/lib/mcp-blackboard-tools.js.map +1 -0
- package/dist/esm/lib/mcp-bridge.js +357 -0
- package/dist/esm/lib/mcp-bridge.js.map +1 -0
- package/dist/esm/lib/mcp-tool-consumer.js +287 -0
- package/dist/esm/lib/mcp-tool-consumer.js.map +1 -0
- package/dist/esm/lib/mcp-tools-control.js +392 -0
- package/dist/esm/lib/mcp-tools-control.js.map +1 -0
- package/dist/esm/lib/mcp-tools-extended.js +371 -0
- package/dist/esm/lib/mcp-tools-extended.js.map +1 -0
- package/dist/esm/lib/mcp-transport-http.js +528 -0
- package/dist/esm/lib/mcp-transport-http.js.map +1 -0
- package/dist/esm/lib/mcp-transport-sse.js +503 -0
- package/dist/esm/lib/mcp-transport-sse.js.map +1 -0
- package/dist/esm/lib/metrics.js +284 -0
- package/dist/esm/lib/metrics.js.map +1 -0
- package/dist/esm/lib/orchestrator-types.js +66 -0
- package/dist/esm/lib/orchestrator-types.js.map +1 -0
- package/dist/esm/lib/otel-bridge.js +167 -0
- package/dist/esm/lib/otel-bridge.js.map +1 -0
- package/dist/esm/lib/partition-planner.js +246 -0
- package/dist/esm/lib/partition-planner.js.map +1 -0
- package/dist/esm/lib/phase-pipeline.js +367 -0
- package/dist/esm/lib/phase-pipeline.js.map +1 -0
- package/dist/esm/lib/playground.js +224 -0
- package/dist/esm/lib/playground.js.map +1 -0
- package/dist/esm/lib/qa-orchestrator.js +296 -0
- package/dist/esm/lib/qa-orchestrator.js.map +1 -0
- package/dist/esm/lib/quadtree.js +259 -0
- package/dist/esm/lib/quadtree.js.map +1 -0
- package/dist/esm/lib/route-classifier.js +217 -0
- package/dist/esm/lib/route-classifier.js.map +1 -0
- package/dist/esm/lib/semantic-search.js +235 -0
- package/dist/esm/lib/semantic-search.js.map +1 -0
- package/dist/esm/lib/shared-blackboard.js +249 -0
- package/dist/esm/lib/shared-blackboard.js.map +1 -0
- package/dist/esm/lib/skill-composer.js +190 -0
- package/dist/esm/lib/skill-composer.js.map +1 -0
- package/dist/esm/lib/speculative-executor.js +107 -0
- package/dist/esm/lib/speculative-executor.js.map +1 -0
- package/dist/esm/lib/strategy-agent.js +626 -0
- package/dist/esm/lib/strategy-agent.js.map +1 -0
- package/dist/esm/lib/swarm-transport.js +307 -0
- package/dist/esm/lib/swarm-transport.js.map +1 -0
- package/dist/esm/lib/swarm-utils.js +510 -0
- package/dist/esm/lib/swarm-utils.js.map +1 -0
- package/dist/esm/lib/task-decomposer.js +272 -0
- package/dist/esm/lib/task-decomposer.js.map +1 -0
- package/dist/esm/lib/telemetry-provider.js +207 -0
- package/dist/esm/lib/telemetry-provider.js.map +1 -0
- package/dist/esm/lib/timeline-scrubber.js +173 -0
- package/dist/esm/lib/timeline-scrubber.js.map +1 -0
- package/dist/esm/lib/topology.js +591 -0
- package/dist/esm/lib/topology.js.map +1 -0
- package/dist/esm/lib/transport-agent.js +366 -0
- package/dist/esm/lib/transport-agent.js.map +1 -0
- package/dist/esm/lib/work-tree-dashboard.js +583 -0
- package/dist/esm/lib/work-tree-dashboard.js.map +1 -0
- package/dist/esm/lib/work-tree-ui.js +333 -0
- package/dist/esm/lib/work-tree-ui.js.map +1 -0
- package/dist/esm/lib/work-tree.js +480 -0
- package/dist/esm/lib/work-tree.js.map +1 -0
- package/dist/esm/run.js +144 -0
- package/dist/esm/run.js.map +1 -0
- package/dist/esm/security.js +1122 -0
- package/dist/esm/security.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/mcp-transport-http.d.ts +203 -0
- package/dist/lib/mcp-transport-http.d.ts.map +1 -0
- package/dist/lib/mcp-transport-http.js +528 -0
- package/dist/lib/mcp-transport-http.js.map +1 -0
- package/dist/lib/phase-pipeline.d.ts +31 -0
- package/dist/lib/phase-pipeline.d.ts.map +1 -1
- package/dist/lib/phase-pipeline.js +93 -1
- package/dist/lib/phase-pipeline.js.map +1 -1
- package/dist/lib/semantic-search.d.ts +42 -6
- package/dist/lib/semantic-search.d.ts.map +1 -1
- package/dist/lib/semantic-search.js +87 -6
- package/dist/lib/semantic-search.js.map +1 -1
- package/package.json +24 -4
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ConfigWatcher — Hot-reload configuration from disk.
|
|
4
|
+
*
|
|
5
|
+
* Uses `fs.watch()` to monitor config files and applies changes to
|
|
6
|
+
* live CONFIG, trust levels, resource profiles, and budget ceilings.
|
|
7
|
+
* Emits events on reload so components can react.
|
|
8
|
+
*
|
|
9
|
+
* @module ConfigWatcher
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.ConfigWatcher = void 0;
|
|
46
|
+
const events_1 = require("events");
|
|
47
|
+
const fs = __importStar(require("fs"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// CONFIG WATCHER
|
|
51
|
+
// ============================================================================
|
|
52
|
+
/**
|
|
53
|
+
* Watches config files on disk and applies changes to live objects.
|
|
54
|
+
*
|
|
55
|
+
* Supports three config file types:
|
|
56
|
+
* - **config.json** — patches `CONFIG` object fields
|
|
57
|
+
* - **trust_levels.json** — array of `{ agentId, level }` applied to AuthGuardian
|
|
58
|
+
* - **budget.json** — `{ ceiling, perAgentCeiling }` applied to FederatedBudget
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* const watcher = new ConfigWatcher({
|
|
63
|
+
* configPath: './data/config.json',
|
|
64
|
+
* trustPath: './data/trust_levels.json',
|
|
65
|
+
* targets: { config: CONFIG, authGuardian: guardian, budget: fed },
|
|
66
|
+
* });
|
|
67
|
+
* watcher.on('reload', (evt) => console.log('Reloaded:', evt.file));
|
|
68
|
+
* watcher.start();
|
|
69
|
+
* // ... later
|
|
70
|
+
* watcher.stop();
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
class ConfigWatcher extends events_1.EventEmitter {
|
|
74
|
+
watchers = [];
|
|
75
|
+
targets;
|
|
76
|
+
configPath;
|
|
77
|
+
trustPath;
|
|
78
|
+
budgetPath;
|
|
79
|
+
debounceMs;
|
|
80
|
+
debounceTimers = new Map();
|
|
81
|
+
running = false;
|
|
82
|
+
constructor(options = {}) {
|
|
83
|
+
super();
|
|
84
|
+
this.configPath = options.configPath;
|
|
85
|
+
this.trustPath = options.trustPath;
|
|
86
|
+
this.budgetPath = options.budgetPath;
|
|
87
|
+
this.targets = options.targets ?? {};
|
|
88
|
+
this.debounceMs = options.debounceMs ?? 300;
|
|
89
|
+
}
|
|
90
|
+
/** Update targets after construction */
|
|
91
|
+
setTargets(targets) {
|
|
92
|
+
Object.assign(this.targets, targets);
|
|
93
|
+
}
|
|
94
|
+
/** Start watching all configured paths */
|
|
95
|
+
start() {
|
|
96
|
+
if (this.running)
|
|
97
|
+
return;
|
|
98
|
+
this.running = true;
|
|
99
|
+
const paths = [this.configPath, this.trustPath, this.budgetPath].filter(Boolean);
|
|
100
|
+
for (const filePath of paths) {
|
|
101
|
+
try {
|
|
102
|
+
if (!fs.existsSync(filePath))
|
|
103
|
+
continue;
|
|
104
|
+
const watcher = fs.watch(filePath, { persistent: false }, (_event) => {
|
|
105
|
+
this.debouncedReload(filePath);
|
|
106
|
+
});
|
|
107
|
+
this.watchers.push(watcher);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// File doesn't exist or not watchable — skip silently
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/** Stop all watchers */
|
|
115
|
+
stop() {
|
|
116
|
+
this.running = false;
|
|
117
|
+
for (const w of this.watchers) {
|
|
118
|
+
try {
|
|
119
|
+
w.close();
|
|
120
|
+
}
|
|
121
|
+
catch { /* ignore */ }
|
|
122
|
+
}
|
|
123
|
+
this.watchers = [];
|
|
124
|
+
for (const timer of this.debounceTimers.values())
|
|
125
|
+
clearTimeout(timer);
|
|
126
|
+
this.debounceTimers.clear();
|
|
127
|
+
}
|
|
128
|
+
/** Manually trigger a reload for a specific file */
|
|
129
|
+
reload(filePath) {
|
|
130
|
+
this.applyReload(filePath);
|
|
131
|
+
}
|
|
132
|
+
/** Whether the watcher is currently active */
|
|
133
|
+
isRunning() {
|
|
134
|
+
return this.running;
|
|
135
|
+
}
|
|
136
|
+
// --------------------------------------------------------------------------
|
|
137
|
+
// INTERNAL
|
|
138
|
+
// --------------------------------------------------------------------------
|
|
139
|
+
debouncedReload(filePath) {
|
|
140
|
+
const existing = this.debounceTimers.get(filePath);
|
|
141
|
+
if (existing)
|
|
142
|
+
clearTimeout(existing);
|
|
143
|
+
this.debounceTimers.set(filePath, setTimeout(() => {
|
|
144
|
+
this.debounceTimers.delete(filePath);
|
|
145
|
+
this.applyReload(filePath);
|
|
146
|
+
}, this.debounceMs));
|
|
147
|
+
}
|
|
148
|
+
applyReload(filePath) {
|
|
149
|
+
try {
|
|
150
|
+
const resolved = path.resolve(filePath);
|
|
151
|
+
const raw = fs.readFileSync(resolved, 'utf-8');
|
|
152
|
+
const data = JSON.parse(raw);
|
|
153
|
+
const changes = [];
|
|
154
|
+
if (resolved === path.resolve(this.configPath ?? '')) {
|
|
155
|
+
this.applyConfig(data, changes);
|
|
156
|
+
}
|
|
157
|
+
else if (resolved === path.resolve(this.trustPath ?? '')) {
|
|
158
|
+
this.applyTrust(data, changes);
|
|
159
|
+
}
|
|
160
|
+
else if (resolved === path.resolve(this.budgetPath ?? '')) {
|
|
161
|
+
this.applyBudget(data, changes);
|
|
162
|
+
}
|
|
163
|
+
const evt = { file: filePath, timestamp: Date.now(), changes };
|
|
164
|
+
this.emit('reload', evt);
|
|
165
|
+
}
|
|
166
|
+
catch (err) {
|
|
167
|
+
const errEvt = {
|
|
168
|
+
file: filePath,
|
|
169
|
+
timestamp: Date.now(),
|
|
170
|
+
error: err instanceof Error ? err.message : String(err),
|
|
171
|
+
};
|
|
172
|
+
this.emit('error', errEvt);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
applyConfig(data, changes) {
|
|
176
|
+
if (!this.targets.config || typeof data !== 'object' || data === null)
|
|
177
|
+
return;
|
|
178
|
+
const obj = data;
|
|
179
|
+
const allowed = new Set([
|
|
180
|
+
'maxParallelAgents', 'defaultTimeout', 'enableTracing',
|
|
181
|
+
'grantTokenTTL', 'maxBlackboardValueSize',
|
|
182
|
+
]);
|
|
183
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
184
|
+
if (allowed.has(key)) {
|
|
185
|
+
this.targets.config[key] = value;
|
|
186
|
+
changes.push(`config.${key}=${JSON.stringify(value)}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
applyTrust(data, changes) {
|
|
191
|
+
if (!this.targets.authGuardian?.setTrustLevel || !Array.isArray(data))
|
|
192
|
+
return;
|
|
193
|
+
for (const entry of data) {
|
|
194
|
+
if (typeof entry === 'object' && entry !== null &&
|
|
195
|
+
'agentId' in entry && 'level' in entry &&
|
|
196
|
+
typeof entry.agentId === 'string' &&
|
|
197
|
+
typeof entry.level === 'number') {
|
|
198
|
+
const { agentId, level } = entry;
|
|
199
|
+
this.targets.authGuardian.setTrustLevel(agentId, level);
|
|
200
|
+
changes.push(`trust.${agentId}=${level}`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
applyBudget(data, changes) {
|
|
205
|
+
if (!this.targets.budget?.setCeiling || typeof data !== 'object' || data === null)
|
|
206
|
+
return;
|
|
207
|
+
const obj = data;
|
|
208
|
+
if (typeof obj.ceiling === 'number') {
|
|
209
|
+
this.targets.budget.setCeiling(obj.ceiling);
|
|
210
|
+
changes.push(`budget.ceiling=${obj.ceiling}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
exports.ConfigWatcher = ConfigWatcher;
|
|
215
|
+
//# sourceMappingURL=config-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-watcher.js","sourceRoot":"","sources":["../../../lib/config-watcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Configurable Consistency Levels for Blackboard Backends
|
|
4
|
+
*
|
|
5
|
+
* Wraps any `BlackboardBackend` with one of three consistency guarantees:
|
|
6
|
+
*
|
|
7
|
+
* - `'eventual'` (default) — writes return immediately; async replication
|
|
8
|
+
* happens in the background. Highest throughput.
|
|
9
|
+
* - `'session'` — read-your-writes guarantee. Every write made
|
|
10
|
+
* by this instance is immediately visible to
|
|
11
|
+
* subsequent reads, even before it propagates to
|
|
12
|
+
* other nodes. Tracked in a local session cache.
|
|
13
|
+
* - `'strong'` — writes are flushed to the backend before the
|
|
14
|
+
* async `writeAsync()` resolves. For backends
|
|
15
|
+
* that implement `FlushableBackend` (e.g.
|
|
16
|
+
* `RedisBackend`, `CrdtBackend`) this guarantees
|
|
17
|
+
* durability before the caller continues.
|
|
18
|
+
*
|
|
19
|
+
* Usage:
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { MemoryBackend } from './blackboard-backend';
|
|
22
|
+
* import { ConsistentBackend } from './consistency';
|
|
23
|
+
*
|
|
24
|
+
* const backend = new ConsistentBackend(new MemoryBackend(), 'session');
|
|
25
|
+
* backend.write('k', 'v', 'agent-1');
|
|
26
|
+
* backend.read('k'); // always returns 'v' in this session
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* Integration with `getBlackboard()`:
|
|
30
|
+
* ```typescript
|
|
31
|
+
* const board = orchestrator.getBlackboard('live', {
|
|
32
|
+
* backend: new RedisBackend(client),
|
|
33
|
+
* consistency: 'strong',
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @module Consistency
|
|
38
|
+
* @version 1.0.0
|
|
39
|
+
* @license MIT
|
|
40
|
+
*/
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.ConsistentBackend = void 0;
|
|
43
|
+
exports.isFlushable = isFlushable;
|
|
44
|
+
/**
|
|
45
|
+
* Type guard — returns `true` if `backend` implements `FlushableBackend`.
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* if (isFlushable(backend)) {
|
|
50
|
+
* await backend.flush();
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
function isFlushable(backend) {
|
|
55
|
+
return typeof backend.flush === 'function';
|
|
56
|
+
}
|
|
57
|
+
// ============================================================================
|
|
58
|
+
// CONSISTENT BACKEND
|
|
59
|
+
// ============================================================================
|
|
60
|
+
/**
|
|
61
|
+
* A `BlackboardBackend` wrapper that adds configurable consistency semantics.
|
|
62
|
+
*
|
|
63
|
+
* Fully satisfies the synchronous `BlackboardBackend` interface so it can be
|
|
64
|
+
* used anywhere a plain backend is accepted. For `'strong'` consistency, use
|
|
65
|
+
* `writeAsync()` to await durability confirmation.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* // Session consistency — read-your-writes
|
|
70
|
+
* const backend = new ConsistentBackend(new MemoryBackend(), 'session');
|
|
71
|
+
* backend.write('task', 'pending', 'agent-1');
|
|
72
|
+
* backend.read('task'); // → 'pending' (guaranteed, even before replication)
|
|
73
|
+
*
|
|
74
|
+
* // Strong consistency with Redis
|
|
75
|
+
* const backend = new ConsistentBackend(new RedisBackend(client), 'strong');
|
|
76
|
+
* await backend.writeAsync('result', data, 'agent-1');
|
|
77
|
+
* // Redis has confirmed the write
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
class ConsistentBackend {
|
|
81
|
+
_backend;
|
|
82
|
+
_level;
|
|
83
|
+
/**
|
|
84
|
+
* Session write cache.
|
|
85
|
+
*
|
|
86
|
+
* - `BlackboardEntry` → written in this session (overrides backend reads)
|
|
87
|
+
* - `null` → deleted in this session (hides backend reads)
|
|
88
|
+
*
|
|
89
|
+
* Only populated for `'session'` consistency.
|
|
90
|
+
*/
|
|
91
|
+
_session = new Map();
|
|
92
|
+
/**
|
|
93
|
+
* Create a new `ConsistentBackend`.
|
|
94
|
+
*
|
|
95
|
+
* @param backend The underlying storage backend to wrap.
|
|
96
|
+
* @param level Consistency level. Defaults to `'eventual'`.
|
|
97
|
+
*/
|
|
98
|
+
constructor(backend, level = 'eventual') {
|
|
99
|
+
this._backend = backend;
|
|
100
|
+
this._level = level;
|
|
101
|
+
}
|
|
102
|
+
// --------------------------------------------------------------------------
|
|
103
|
+
// BlackboardBackend interface
|
|
104
|
+
// --------------------------------------------------------------------------
|
|
105
|
+
/**
|
|
106
|
+
* Read an entry.
|
|
107
|
+
*
|
|
108
|
+
* - `eventual` / `strong`: delegates directly to the underlying backend.
|
|
109
|
+
* - `session`: returns the session-cached entry if present; falls back to
|
|
110
|
+
* the backend. Returns `null` for session-deleted keys even if the backend
|
|
111
|
+
* still has them.
|
|
112
|
+
*/
|
|
113
|
+
read(key) {
|
|
114
|
+
if (this._level === 'session') {
|
|
115
|
+
const cached = this._session.get(key);
|
|
116
|
+
if (cached === undefined) {
|
|
117
|
+
// Not in session cache — fall through to backend
|
|
118
|
+
}
|
|
119
|
+
else if (cached === null) {
|
|
120
|
+
// Session-deleted tombstone
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
// Live session entry — check expiry
|
|
125
|
+
if (this._isExpired(cached)) {
|
|
126
|
+
this._session.delete(key);
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
return cached;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return this._backend.read(key);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Write a value synchronously.
|
|
136
|
+
*
|
|
137
|
+
* For all consistency levels this writes immediately to the underlying
|
|
138
|
+
* backend. For `'session'` the result is also cached locally so subsequent
|
|
139
|
+
* `read()` calls see it without waiting for replication.
|
|
140
|
+
*
|
|
141
|
+
* For `'strong'` consistency, prefer `writeAsync()` to await durability.
|
|
142
|
+
*/
|
|
143
|
+
write(key, value, sourceAgent, ttl) {
|
|
144
|
+
const entry = this._backend.write(key, value, sourceAgent, ttl);
|
|
145
|
+
if (this._level === 'session') {
|
|
146
|
+
this._session.set(key, entry);
|
|
147
|
+
}
|
|
148
|
+
return entry;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Delete an entry.
|
|
152
|
+
*
|
|
153
|
+
* For `'session'` consistency, also records a session-tombstone so the key
|
|
154
|
+
* appears deleted to subsequent `read()` calls in this session.
|
|
155
|
+
*/
|
|
156
|
+
delete(key) {
|
|
157
|
+
const result = this._backend.delete(key);
|
|
158
|
+
if (this._level === 'session') {
|
|
159
|
+
this._session.set(key, null); // tombstone
|
|
160
|
+
}
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Return all non-expired, non-deleted keys.
|
|
165
|
+
*
|
|
166
|
+
* For `'session'` consistency, session-written keys are included even if
|
|
167
|
+
* not yet visible in the backend; session-deleted keys are excluded.
|
|
168
|
+
*/
|
|
169
|
+
listKeys() {
|
|
170
|
+
if (this._level !== 'session') {
|
|
171
|
+
return this._backend.listKeys();
|
|
172
|
+
}
|
|
173
|
+
// Start with backend keys, then overlay session mutations
|
|
174
|
+
const backendKeys = new Set(this._backend.listKeys());
|
|
175
|
+
// Add session-written keys (not yet in backend, or overriding backend)
|
|
176
|
+
for (const [key, entry] of this._session.entries()) {
|
|
177
|
+
if (entry === null) {
|
|
178
|
+
// Session delete — remove from result
|
|
179
|
+
backendKeys.delete(key);
|
|
180
|
+
}
|
|
181
|
+
else if (!this._isExpired(entry)) {
|
|
182
|
+
backendKeys.add(key);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return Array.from(backendKeys);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Return a snapshot of all non-expired, non-deleted entries.
|
|
189
|
+
*
|
|
190
|
+
* For `'session'` consistency, session writes overlay the backend snapshot.
|
|
191
|
+
*/
|
|
192
|
+
getSnapshot() {
|
|
193
|
+
if (this._level !== 'session') {
|
|
194
|
+
return this._backend.getSnapshot();
|
|
195
|
+
}
|
|
196
|
+
// Start from backend snapshot, apply session overlay
|
|
197
|
+
const result = { ...this._backend.getSnapshot() };
|
|
198
|
+
for (const [key, entry] of this._session.entries()) {
|
|
199
|
+
if (entry === null) {
|
|
200
|
+
// Session delete
|
|
201
|
+
delete result[key];
|
|
202
|
+
}
|
|
203
|
+
else if (!this._isExpired(entry)) {
|
|
204
|
+
result[key] = entry;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return result;
|
|
208
|
+
}
|
|
209
|
+
// --------------------------------------------------------------------------
|
|
210
|
+
// Extended consistency API
|
|
211
|
+
// --------------------------------------------------------------------------
|
|
212
|
+
/**
|
|
213
|
+
* Write a value and, for `'strong'` consistency, await durability
|
|
214
|
+
* confirmation from the backend.
|
|
215
|
+
*
|
|
216
|
+
* - `eventual` / `session`: behaves identically to `write()` but returns
|
|
217
|
+
* a `Promise` for API uniformity.
|
|
218
|
+
* - `strong` + `FlushableBackend`: calls `backend.flush()` after the write
|
|
219
|
+
* and resolves only after the flush completes.
|
|
220
|
+
* - `strong` + non-flushable backend: writes synchronously and resolves
|
|
221
|
+
* immediately (backend writes are already synchronous/durable).
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```typescript
|
|
225
|
+
* const entry = await backend.writeAsync('checkpoint', data, 'agent-1');
|
|
226
|
+
* // Under 'strong' + RedisBackend: Redis has persisted the entry by here
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
async writeAsync(key, value, sourceAgent, ttl) {
|
|
230
|
+
const entry = this.write(key, value, sourceAgent, ttl);
|
|
231
|
+
if (this._level === 'strong' && isFlushable(this._backend)) {
|
|
232
|
+
await this._backend.flush();
|
|
233
|
+
}
|
|
234
|
+
return entry;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* The configured consistency level.
|
|
238
|
+
*/
|
|
239
|
+
get consistencyLevel() {
|
|
240
|
+
return this._level;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* The underlying backend being wrapped.
|
|
244
|
+
*/
|
|
245
|
+
get backend() {
|
|
246
|
+
return this._backend;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Number of entries currently in the session cache (live + tombstones).
|
|
250
|
+
* Always `0` for `'eventual'` and `'strong'` levels.
|
|
251
|
+
*/
|
|
252
|
+
get sessionSize() {
|
|
253
|
+
return this._session.size;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Clear the session write cache without modifying the underlying backend.
|
|
257
|
+
*
|
|
258
|
+
* After calling this, `read()` will reflect the backend state directly.
|
|
259
|
+
* Only meaningful for `'session'` consistency.
|
|
260
|
+
*/
|
|
261
|
+
clearSession() {
|
|
262
|
+
this._session.clear();
|
|
263
|
+
}
|
|
264
|
+
// --------------------------------------------------------------------------
|
|
265
|
+
// Private helpers
|
|
266
|
+
// --------------------------------------------------------------------------
|
|
267
|
+
_isExpired(entry) {
|
|
268
|
+
if (!entry.ttl)
|
|
269
|
+
return false;
|
|
270
|
+
return Date.now() > new Date(entry.timestamp).getTime() + entry.ttl * 1000;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
exports.ConsistentBackend = ConsistentBackend;
|
|
274
|
+
//# sourceMappingURL=consistency.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consistency.js","sourceRoot":"","sources":["../../../lib/consistency.ts"],"names":[],"mappings":"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"}
|