@darkiceinteractive/mcp-conductor 2.0.0-alpha.1 → 3.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -5
- package/dist/bin/cli.d.ts +20 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +260 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/bridge/http-server.d.ts +26 -0
- package/dist/bridge/http-server.d.ts.map +1 -1
- package/dist/bridge/http-server.js +30 -2
- package/dist/bridge/http-server.js.map +1 -1
- package/dist/bridge/index.d.ts +1 -0
- package/dist/bridge/index.d.ts.map +1 -1
- package/dist/bridge/index.js +1 -0
- package/dist/bridge/index.js.map +1 -1
- package/dist/bridge/pool.d.ts +95 -0
- package/dist/bridge/pool.d.ts.map +1 -0
- package/dist/bridge/pool.js +384 -0
- package/dist/bridge/pool.js.map +1 -0
- package/dist/cache/cache.d.ts +43 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +167 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/delta.d.ts +32 -0
- package/dist/cache/delta.d.ts.map +1 -0
- package/dist/cache/delta.js +131 -0
- package/dist/cache/delta.js.map +1 -0
- package/dist/cache/disk.d.ts +65 -0
- package/dist/cache/disk.d.ts.map +1 -0
- package/dist/cache/disk.js +238 -0
- package/dist/cache/disk.js.map +1 -0
- package/dist/cache/index.d.ts +53 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +12 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/key.d.ts +44 -0
- package/dist/cache/key.d.ts.map +1 -0
- package/dist/cache/key.js +83 -0
- package/dist/cache/key.js.map +1 -0
- package/dist/cache/lru.d.ts +57 -0
- package/dist/cache/lru.d.ts.map +1 -0
- package/dist/cache/lru.js +112 -0
- package/dist/cache/lru.js.map +1 -0
- package/dist/cache/policy.d.ts +34 -0
- package/dist/cache/policy.d.ts.map +1 -0
- package/dist/cache/policy.js +95 -0
- package/dist/cache/policy.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +33 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +135 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/export-servers.d.ts +22 -0
- package/dist/cli/commands/export-servers.d.ts.map +1 -0
- package/dist/cli/commands/export-servers.js +45 -0
- package/dist/cli/commands/export-servers.js.map +1 -0
- package/dist/cli/commands/import-servers.d.ts +57 -0
- package/dist/cli/commands/import-servers.d.ts.map +1 -0
- package/dist/cli/commands/import-servers.js +137 -0
- package/dist/cli/commands/import-servers.js.map +1 -0
- package/dist/cli/commands/routing.d.ts +34 -0
- package/dist/cli/commands/routing.d.ts.map +1 -0
- package/dist/cli/commands/routing.js +60 -0
- package/dist/cli/commands/routing.js.map +1 -0
- package/dist/cli/commands/test-server.d.ts +34 -0
- package/dist/cli/commands/test-server.d.ts.map +1 -0
- package/dist/cli/commands/test-server.js +86 -0
- package/dist/cli/commands/test-server.js.map +1 -0
- package/dist/cli/daemon.d.ts +60 -0
- package/dist/cli/daemon.d.ts.map +1 -0
- package/dist/cli/daemon.js +244 -0
- package/dist/cli/daemon.js.map +1 -0
- package/dist/cli/replay.d.ts +16 -0
- package/dist/cli/replay.d.ts.map +1 -0
- package/dist/cli/replay.js +89 -0
- package/dist/cli/replay.js.map +1 -0
- package/dist/cli/wizard/setup.d.ts +12 -0
- package/dist/cli/wizard/setup.d.ts.map +1 -0
- package/dist/cli/wizard/setup.js +71 -0
- package/dist/cli/wizard/setup.js.map +1 -0
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +4 -1
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/schema.d.ts +34 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/daemon/client.d.ts +97 -0
- package/dist/daemon/client.d.ts.map +1 -0
- package/dist/daemon/client.js +279 -0
- package/dist/daemon/client.js.map +1 -0
- package/dist/daemon/discovery.d.ts +50 -0
- package/dist/daemon/discovery.d.ts.map +1 -0
- package/dist/daemon/discovery.js +104 -0
- package/dist/daemon/discovery.js.map +1 -0
- package/dist/daemon/index.d.ts +16 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +11 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/sandbox-api.d.ts +45 -0
- package/dist/daemon/sandbox-api.d.ts.map +1 -0
- package/dist/daemon/sandbox-api.js +74 -0
- package/dist/daemon/sandbox-api.js.map +1 -0
- package/dist/daemon/server.d.ts +65 -0
- package/dist/daemon/server.d.ts.map +1 -0
- package/dist/daemon/server.js +351 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/daemon/shared-kv.d.ts +81 -0
- package/dist/daemon/shared-kv.d.ts.map +1 -0
- package/dist/daemon/shared-kv.js +215 -0
- package/dist/daemon/shared-kv.js.map +1 -0
- package/dist/daemon/shared-lock.d.ts +71 -0
- package/dist/daemon/shared-lock.d.ts.map +1 -0
- package/dist/daemon/shared-lock.js +119 -0
- package/dist/daemon/shared-lock.js.map +1 -0
- package/dist/hub/mcp-hub.d.ts +23 -0
- package/dist/hub/mcp-hub.d.ts.map +1 -1
- package/dist/hub/mcp-hub.js +34 -1
- package/dist/hub/mcp-hub.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/observability/anomaly.d.ts +67 -0
- package/dist/observability/anomaly.d.ts.map +1 -0
- package/dist/observability/anomaly.js +141 -0
- package/dist/observability/anomaly.js.map +1 -0
- package/dist/observability/cost-predictor.d.ts +49 -0
- package/dist/observability/cost-predictor.d.ts.map +1 -0
- package/dist/observability/cost-predictor.js +145 -0
- package/dist/observability/cost-predictor.js.map +1 -0
- package/dist/observability/hot-path.d.ts +49 -0
- package/dist/observability/hot-path.d.ts.map +1 -0
- package/dist/observability/hot-path.js +125 -0
- package/dist/observability/hot-path.js.map +1 -0
- package/dist/observability/index.d.ts +10 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +10 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/replay.d.ts +104 -0
- package/dist/observability/replay.d.ts.map +1 -0
- package/dist/observability/replay.js +239 -0
- package/dist/observability/replay.js.map +1 -0
- package/dist/registry/built-in-recommendations.d.ts +54 -0
- package/dist/registry/built-in-recommendations.d.ts.map +1 -0
- package/dist/registry/built-in-recommendations.js +65 -0
- package/dist/registry/built-in-recommendations.js.map +1 -0
- package/dist/registry/events.d.ts +26 -0
- package/dist/registry/events.d.ts.map +1 -0
- package/dist/registry/events.js +22 -0
- package/dist/registry/events.js.map +1 -0
- package/dist/registry/index.d.ts +159 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +12 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/registry/registry.d.ts +87 -0
- package/dist/registry/registry.d.ts.map +1 -0
- package/dist/registry/registry.js +294 -0
- package/dist/registry/registry.js.map +1 -0
- package/dist/registry/snapshot.d.ts +42 -0
- package/dist/registry/snapshot.d.ts.map +1 -0
- package/dist/registry/snapshot.js +71 -0
- package/dist/registry/snapshot.js.map +1 -0
- package/dist/registry/typegen.d.ts +48 -0
- package/dist/registry/typegen.d.ts.map +1 -0
- package/dist/registry/typegen.js +200 -0
- package/dist/registry/typegen.js.map +1 -0
- package/dist/registry/validator.d.ts +23 -0
- package/dist/registry/validator.d.ts.map +1 -0
- package/dist/registry/validator.js +50 -0
- package/dist/registry/validator.js.map +1 -0
- package/dist/reliability/breaker.d.ts +57 -0
- package/dist/reliability/breaker.d.ts.map +1 -0
- package/dist/reliability/breaker.js +130 -0
- package/dist/reliability/breaker.js.map +1 -0
- package/dist/reliability/errors.d.ts +78 -0
- package/dist/reliability/errors.d.ts.map +1 -0
- package/dist/reliability/errors.js +160 -0
- package/dist/reliability/errors.js.map +1 -0
- package/dist/reliability/gateway.d.ts +88 -0
- package/dist/reliability/gateway.d.ts.map +1 -0
- package/dist/reliability/gateway.js +180 -0
- package/dist/reliability/gateway.js.map +1 -0
- package/dist/reliability/index.d.ts +20 -0
- package/dist/reliability/index.d.ts.map +1 -0
- package/dist/reliability/index.js +16 -0
- package/dist/reliability/index.js.map +1 -0
- package/dist/reliability/profile.d.ts +49 -0
- package/dist/reliability/profile.d.ts.map +1 -0
- package/dist/reliability/profile.js +58 -0
- package/dist/reliability/profile.js.map +1 -0
- package/dist/reliability/retry.d.ts +39 -0
- package/dist/reliability/retry.d.ts.map +1 -0
- package/dist/reliability/retry.js +51 -0
- package/dist/reliability/retry.js.map +1 -0
- package/dist/reliability/timeout.d.ts +34 -0
- package/dist/reliability/timeout.d.ts.map +1 -0
- package/dist/reliability/timeout.js +53 -0
- package/dist/reliability/timeout.js.map +1 -0
- package/dist/runtime/executor.d.ts.map +1 -1
- package/dist/runtime/executor.js +78 -13
- package/dist/runtime/executor.js.map +1 -1
- package/dist/runtime/findtool/embed.d.ts +28 -0
- package/dist/runtime/findtool/embed.d.ts.map +1 -0
- package/dist/runtime/findtool/embed.js +85 -0
- package/dist/runtime/findtool/embed.js.map +1 -0
- package/dist/runtime/findtool/index.d.ts +52 -0
- package/dist/runtime/findtool/index.d.ts.map +1 -0
- package/dist/runtime/findtool/index.js +78 -0
- package/dist/runtime/findtool/index.js.map +1 -0
- package/dist/runtime/findtool/vector-index.d.ts +53 -0
- package/dist/runtime/findtool/vector-index.d.ts.map +1 -0
- package/dist/runtime/findtool/vector-index.js +71 -0
- package/dist/runtime/findtool/vector-index.js.map +1 -0
- package/dist/runtime/helpers/budget.d.ts +27 -0
- package/dist/runtime/helpers/budget.d.ts.map +1 -0
- package/dist/runtime/helpers/budget.js +103 -0
- package/dist/runtime/helpers/budget.js.map +1 -0
- package/dist/runtime/helpers/compact.d.ts +32 -0
- package/dist/runtime/helpers/compact.d.ts.map +1 -0
- package/dist/runtime/helpers/compact.js +93 -0
- package/dist/runtime/helpers/compact.js.map +1 -0
- package/dist/runtime/helpers/delta.d.ts +45 -0
- package/dist/runtime/helpers/delta.d.ts.map +1 -0
- package/dist/runtime/helpers/delta.js +116 -0
- package/dist/runtime/helpers/delta.js.map +1 -0
- package/dist/runtime/helpers/index.d.ts +16 -0
- package/dist/runtime/helpers/index.d.ts.map +1 -0
- package/dist/runtime/helpers/index.js +13 -0
- package/dist/runtime/helpers/index.js.map +1 -0
- package/dist/runtime/helpers/summarize.d.ts +24 -0
- package/dist/runtime/helpers/summarize.d.ts.map +1 -0
- package/dist/runtime/helpers/summarize.js +124 -0
- package/dist/runtime/helpers/summarize.js.map +1 -0
- package/dist/runtime/helpers/worker-preload.d.ts +25 -0
- package/dist/runtime/helpers/worker-preload.d.ts.map +1 -0
- package/dist/runtime/helpers/worker-preload.js +223 -0
- package/dist/runtime/helpers/worker-preload.js.map +1 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +1 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/pool/index.d.ts +11 -0
- package/dist/runtime/pool/index.d.ts.map +1 -0
- package/dist/runtime/pool/index.js +8 -0
- package/dist/runtime/pool/index.js.map +1 -0
- package/dist/runtime/pool/recycle.d.ts +44 -0
- package/dist/runtime/pool/recycle.d.ts.map +1 -0
- package/dist/runtime/pool/recycle.js +50 -0
- package/dist/runtime/pool/recycle.js.map +1 -0
- package/dist/runtime/pool/worker-pool.d.ts +77 -0
- package/dist/runtime/pool/worker-pool.d.ts.map +1 -0
- package/dist/runtime/pool/worker-pool.js +216 -0
- package/dist/runtime/pool/worker-pool.js.map +1 -0
- package/dist/runtime/pool/worker.d.ts +80 -0
- package/dist/runtime/pool/worker.d.ts.map +1 -0
- package/dist/runtime/pool/worker.js +324 -0
- package/dist/runtime/pool/worker.js.map +1 -0
- package/dist/server/mcp-server.d.ts +1 -0
- package/dist/server/mcp-server.d.ts.map +1 -1
- package/dist/server/mcp-server.js +423 -2
- package/dist/server/mcp-server.js.map +1 -1
- package/dist/server/passthrough-registrar.d.ts +73 -0
- package/dist/server/passthrough-registrar.d.ts.map +1 -0
- package/dist/server/passthrough-registrar.js +110 -0
- package/dist/server/passthrough-registrar.js.map +1 -0
- package/dist/skills/skills-engine.d.ts +9 -1
- package/dist/skills/skills-engine.d.ts.map +1 -1
- package/dist/skills/skills-engine.js +20 -3
- package/dist/skills/skills-engine.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/tokenize.d.ts +55 -0
- package/dist/utils/tokenize.d.ts.map +1 -0
- package/dist/utils/tokenize.js +205 -0
- package/dist/utils/tokenize.js.map +1 -0
- package/dist/version.d.ts +3 -3
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +3 -3
- package/dist/version.js.map +1 -1
- package/package.json +12 -2
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend Connection Pool
|
|
3
|
+
*
|
|
4
|
+
* Maintains persistent stdio connections to MCP backend servers, multiplexes
|
|
5
|
+
* JSON-RPC requests over the same channel, and respawns crashed backends
|
|
6
|
+
* within 1 second. Eliminates per-request spawn overhead.
|
|
7
|
+
*
|
|
8
|
+
* Design:
|
|
9
|
+
* - Each server gets [min, max] connections whose lifecycle is managed here
|
|
10
|
+
* - JSON-RPC multiplexing: requests tagged with a unique id; responses routed
|
|
11
|
+
* back to the correct in-flight caller via a pending-map
|
|
12
|
+
* - Idle timer: connections unused for `idleTimeoutMs` are gracefully closed
|
|
13
|
+
* - Crash recovery: `close` event triggers automatic respawn
|
|
14
|
+
*
|
|
15
|
+
* @module bridge/pool
|
|
16
|
+
*/
|
|
17
|
+
import { EventEmitter } from 'node:events';
|
|
18
|
+
import type { ConnectionPoolConfig } from '../config/schema.js';
|
|
19
|
+
export interface PoolStats {
|
|
20
|
+
totalConnections: number;
|
|
21
|
+
idleConnections: number;
|
|
22
|
+
busyConnections: number;
|
|
23
|
+
serversTracked: number;
|
|
24
|
+
pendingAcquires: number;
|
|
25
|
+
}
|
|
26
|
+
/** Opaque handle returned by `acquire()`. Pass back to `release()`. */
|
|
27
|
+
export interface PooledConnection {
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly serverKey: string;
|
|
30
|
+
/** Send a multiplexed JSON-RPC call; resolves with the parsed response. */
|
|
31
|
+
call(method: string, params?: unknown): Promise<unknown>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Factory function that creates a new stdio channel to a backend.
|
|
35
|
+
* Returns a send function and a closer; delivers received lines via callback.
|
|
36
|
+
*/
|
|
37
|
+
export type ConnectionFactory = (opts: {
|
|
38
|
+
onLine: (line: string) => void;
|
|
39
|
+
onClose: () => void;
|
|
40
|
+
onError: (err: Error) => void;
|
|
41
|
+
}) => {
|
|
42
|
+
write: (line: string) => boolean;
|
|
43
|
+
close: () => void;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* A connection pool for MCP backend servers.
|
|
47
|
+
*
|
|
48
|
+
* Usage:
|
|
49
|
+
* ```ts
|
|
50
|
+
* pool.registerServer('my-server', factory);
|
|
51
|
+
* const conn = await pool.acquire('my-server');
|
|
52
|
+
* const result = await conn.call('tools/list');
|
|
53
|
+
* pool.release(conn);
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare class ConnectionPool extends EventEmitter {
|
|
57
|
+
private readonly opts;
|
|
58
|
+
private readonly servers;
|
|
59
|
+
private isShuttingDown;
|
|
60
|
+
constructor(options?: ConnectionPoolConfig);
|
|
61
|
+
/**
|
|
62
|
+
* Register a backend server with its connection factory.
|
|
63
|
+
* Call this before `acquire()`. Pre-warms `minConnectionsPerServer`
|
|
64
|
+
* connections immediately.
|
|
65
|
+
*/
|
|
66
|
+
registerServer(serverKey: string, factory: ConnectionFactory): void;
|
|
67
|
+
/**
|
|
68
|
+
* Acquire an idle connection for `serverKey`.
|
|
69
|
+
*
|
|
70
|
+
* If all connections are busy and count < max, spawns a new one.
|
|
71
|
+
* If at max, waits up to `acquireTimeoutMs` for a release.
|
|
72
|
+
*/
|
|
73
|
+
acquire(serverKey: string): Promise<PooledConnection>;
|
|
74
|
+
/**
|
|
75
|
+
* Return a connection to the pool.
|
|
76
|
+
* Idle timer is (re)started; if waiters are queued, hands off immediately.
|
|
77
|
+
*/
|
|
78
|
+
release(connection: PooledConnection): void;
|
|
79
|
+
/** Gracefully drain all connections and stop accepting new ones. */
|
|
80
|
+
shutdown(): Promise<void>;
|
|
81
|
+
/** Snapshot of pool health metrics. */
|
|
82
|
+
stats(): PoolStats;
|
|
83
|
+
private _findIdle;
|
|
84
|
+
private _markBusy;
|
|
85
|
+
private _toPublic;
|
|
86
|
+
private _rpcCall;
|
|
87
|
+
private _spawnConnection;
|
|
88
|
+
private _handleLine;
|
|
89
|
+
private _handleClose;
|
|
90
|
+
private _handleError;
|
|
91
|
+
private _startIdleTimer;
|
|
92
|
+
private _closeInternal;
|
|
93
|
+
private _drainWaiters;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=pool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../src/bridge/pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAMhE,MAAM,WAAW,SAAS;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,uEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,2EAA2E;IAC3E,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1D;AA6CD;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE;IACrC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;CAC/B,KAAK;IACJ,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACjC,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC;AAaF;;;;;;;;;;GAUG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiC;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,GAAE,oBAAyB;IAK9C;;;;OAIG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAoBnE;;;;;OAKG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAuC3D;;;OAGG;IACH,OAAO,CAAC,UAAU,EAAE,gBAAgB,GAAG,IAAI;IAuB3C,oEAAoE;IAC9D,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB/B,uCAAuC;IACvC,KAAK,IAAI,SAAS;IA6BlB,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,QAAQ;YAkBF,gBAAgB;IAiD9B,OAAO,CAAC,WAAW;IAkCnB,OAAO,CAAC,YAAY;IA6CpB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,cAAc;IAsBtB,OAAO,CAAC,aAAa;CAUtB"}
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend Connection Pool
|
|
3
|
+
*
|
|
4
|
+
* Maintains persistent stdio connections to MCP backend servers, multiplexes
|
|
5
|
+
* JSON-RPC requests over the same channel, and respawns crashed backends
|
|
6
|
+
* within 1 second. Eliminates per-request spawn overhead.
|
|
7
|
+
*
|
|
8
|
+
* Design:
|
|
9
|
+
* - Each server gets [min, max] connections whose lifecycle is managed here
|
|
10
|
+
* - JSON-RPC multiplexing: requests tagged with a unique id; responses routed
|
|
11
|
+
* back to the correct in-flight caller via a pending-map
|
|
12
|
+
* - Idle timer: connections unused for `idleTimeoutMs` are gracefully closed
|
|
13
|
+
* - Crash recovery: `close` event triggers automatic respawn
|
|
14
|
+
*
|
|
15
|
+
* @module bridge/pool
|
|
16
|
+
*/
|
|
17
|
+
import { EventEmitter } from 'node:events';
|
|
18
|
+
import { logger } from '../utils/index.js';
|
|
19
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
20
|
+
// ConnectionPool
|
|
21
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
22
|
+
const DEFAULT_OPTIONS = {
|
|
23
|
+
minConnectionsPerServer: 1,
|
|
24
|
+
maxConnectionsPerServer: 4,
|
|
25
|
+
idleTimeoutMs: 300_000,
|
|
26
|
+
acquireTimeoutMs: 5_000,
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* A connection pool for MCP backend servers.
|
|
30
|
+
*
|
|
31
|
+
* Usage:
|
|
32
|
+
* ```ts
|
|
33
|
+
* pool.registerServer('my-server', factory);
|
|
34
|
+
* const conn = await pool.acquire('my-server');
|
|
35
|
+
* const result = await conn.call('tools/list');
|
|
36
|
+
* pool.release(conn);
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export class ConnectionPool extends EventEmitter {
|
|
40
|
+
opts;
|
|
41
|
+
servers = new Map();
|
|
42
|
+
isShuttingDown = false;
|
|
43
|
+
constructor(options = {}) {
|
|
44
|
+
super();
|
|
45
|
+
this.opts = { ...DEFAULT_OPTIONS, ...options };
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Register a backend server with its connection factory.
|
|
49
|
+
* Call this before `acquire()`. Pre-warms `minConnectionsPerServer`
|
|
50
|
+
* connections immediately.
|
|
51
|
+
*/
|
|
52
|
+
registerServer(serverKey, factory) {
|
|
53
|
+
if (this.servers.has(serverKey))
|
|
54
|
+
return;
|
|
55
|
+
const entry = {
|
|
56
|
+
key: serverKey,
|
|
57
|
+
connections: new Map(),
|
|
58
|
+
waiting: [],
|
|
59
|
+
factory,
|
|
60
|
+
spawning: 0,
|
|
61
|
+
};
|
|
62
|
+
this.servers.set(serverKey, entry);
|
|
63
|
+
// Pre-warm minimum connections
|
|
64
|
+
for (let i = 0; i < this.opts.minConnectionsPerServer; i++) {
|
|
65
|
+
this._spawnConnection(entry).catch((err) => {
|
|
66
|
+
logger.warn('ConnectionPool: pre-warm spawn failed', { serverKey, err: String(err) });
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Acquire an idle connection for `serverKey`.
|
|
72
|
+
*
|
|
73
|
+
* If all connections are busy and count < max, spawns a new one.
|
|
74
|
+
* If at max, waits up to `acquireTimeoutMs` for a release.
|
|
75
|
+
*/
|
|
76
|
+
async acquire(serverKey) {
|
|
77
|
+
if (this.isShuttingDown) {
|
|
78
|
+
throw new Error(`ConnectionPool is shutting down`);
|
|
79
|
+
}
|
|
80
|
+
const entry = this.servers.get(serverKey);
|
|
81
|
+
if (!entry) {
|
|
82
|
+
throw new Error(`ConnectionPool: unknown server "${serverKey}". Call registerServer() first.`);
|
|
83
|
+
}
|
|
84
|
+
// Try to find an idle connection
|
|
85
|
+
const idle = this._findIdle(entry);
|
|
86
|
+
if (idle) {
|
|
87
|
+
return this._markBusy(idle);
|
|
88
|
+
}
|
|
89
|
+
// Spawn a new connection if under max
|
|
90
|
+
const totalActive = entry.connections.size + entry.spawning;
|
|
91
|
+
if (totalActive < this.opts.maxConnectionsPerServer) {
|
|
92
|
+
const conn = await this._spawnConnection(entry);
|
|
93
|
+
return this._markBusy(conn);
|
|
94
|
+
}
|
|
95
|
+
// All at max — wait for a release
|
|
96
|
+
return new Promise((resolve, reject) => {
|
|
97
|
+
const timer = setTimeout(() => {
|
|
98
|
+
const idx = entry.waiting.indexOf(waiter);
|
|
99
|
+
if (idx !== -1)
|
|
100
|
+
entry.waiting.splice(idx, 1);
|
|
101
|
+
reject(new Error(`ConnectionPool: acquire timeout after ${this.opts.acquireTimeoutMs}ms for "${serverKey}"`));
|
|
102
|
+
}, this.opts.acquireTimeoutMs);
|
|
103
|
+
// Allow the timer to be GC'd without blocking Node exit
|
|
104
|
+
if (timer.unref)
|
|
105
|
+
timer.unref();
|
|
106
|
+
const waiter = { resolve, reject, timer };
|
|
107
|
+
entry.waiting.push(waiter);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Return a connection to the pool.
|
|
112
|
+
* Idle timer is (re)started; if waiters are queued, hands off immediately.
|
|
113
|
+
*/
|
|
114
|
+
release(connection) {
|
|
115
|
+
const entry = this.servers.get(connection.serverKey);
|
|
116
|
+
if (!entry)
|
|
117
|
+
return;
|
|
118
|
+
const internal = entry.connections.get(connection.id);
|
|
119
|
+
if (!internal || internal.closed)
|
|
120
|
+
return;
|
|
121
|
+
internal.busy = false;
|
|
122
|
+
// Drain waiting queue first
|
|
123
|
+
if (entry.waiting.length > 0) {
|
|
124
|
+
const waiter = entry.waiting.shift();
|
|
125
|
+
clearTimeout(waiter.timer);
|
|
126
|
+
// Mark busy synchronously before handing off
|
|
127
|
+
internal.busy = true;
|
|
128
|
+
waiter.resolve(this._toPublic(internal));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
// Start idle timer
|
|
132
|
+
this._startIdleTimer(entry, internal);
|
|
133
|
+
}
|
|
134
|
+
/** Gracefully drain all connections and stop accepting new ones. */
|
|
135
|
+
async shutdown() {
|
|
136
|
+
this.isShuttingDown = true;
|
|
137
|
+
for (const entry of this.servers.values()) {
|
|
138
|
+
// Reject all waiting acquires
|
|
139
|
+
for (const waiter of entry.waiting) {
|
|
140
|
+
clearTimeout(waiter.timer);
|
|
141
|
+
waiter.reject(new Error('ConnectionPool shut down'));
|
|
142
|
+
}
|
|
143
|
+
entry.waiting.length = 0;
|
|
144
|
+
// Close all connections
|
|
145
|
+
for (const conn of entry.connections.values()) {
|
|
146
|
+
this._closeInternal(conn);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
this.servers.clear();
|
|
150
|
+
logger.info('ConnectionPool: shut down complete');
|
|
151
|
+
}
|
|
152
|
+
/** Snapshot of pool health metrics. */
|
|
153
|
+
stats() {
|
|
154
|
+
let total = 0;
|
|
155
|
+
let idle = 0;
|
|
156
|
+
let busy = 0;
|
|
157
|
+
let pending = 0;
|
|
158
|
+
for (const entry of this.servers.values()) {
|
|
159
|
+
for (const conn of entry.connections.values()) {
|
|
160
|
+
if (conn.closed)
|
|
161
|
+
continue;
|
|
162
|
+
total++;
|
|
163
|
+
if (conn.busy)
|
|
164
|
+
busy++;
|
|
165
|
+
else
|
|
166
|
+
idle++;
|
|
167
|
+
}
|
|
168
|
+
pending += entry.waiting.length;
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
totalConnections: total,
|
|
172
|
+
idleConnections: idle,
|
|
173
|
+
busyConnections: busy,
|
|
174
|
+
serversTracked: this.servers.size,
|
|
175
|
+
pendingAcquires: pending,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
179
|
+
// Private helpers
|
|
180
|
+
// ───────────────────────────────────────────────────────────────────────────
|
|
181
|
+
_findIdle(entry) {
|
|
182
|
+
for (const conn of entry.connections.values()) {
|
|
183
|
+
if (!conn.busy && !conn.closed)
|
|
184
|
+
return conn;
|
|
185
|
+
}
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
_markBusy(conn) {
|
|
189
|
+
conn.busy = true;
|
|
190
|
+
// Cancel idle timer if active
|
|
191
|
+
if (conn.idleTimer) {
|
|
192
|
+
clearTimeout(conn.idleTimer);
|
|
193
|
+
conn.idleTimer = null;
|
|
194
|
+
}
|
|
195
|
+
return this._toPublic(conn);
|
|
196
|
+
}
|
|
197
|
+
_toPublic(internal) {
|
|
198
|
+
return {
|
|
199
|
+
id: internal.id,
|
|
200
|
+
serverKey: internal.serverKey,
|
|
201
|
+
call: (method, params) => this._rpcCall(internal, method, params),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
_rpcCall(conn, method, params) {
|
|
205
|
+
if (conn.closed || !conn.writeLine) {
|
|
206
|
+
return Promise.reject(new Error(`Connection ${conn.id} is closed`));
|
|
207
|
+
}
|
|
208
|
+
const id = conn.nextRequestId++;
|
|
209
|
+
const message = JSON.stringify({ jsonrpc: '2.0', id, method, params: params ?? {} });
|
|
210
|
+
return new Promise((resolve, reject) => {
|
|
211
|
+
conn.pending.set(id, { resolve, reject });
|
|
212
|
+
const ok = conn.writeLine(message + '\n');
|
|
213
|
+
if (!ok) {
|
|
214
|
+
conn.pending.delete(id);
|
|
215
|
+
reject(new Error(`Write failed on connection ${conn.id}`));
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
async _spawnConnection(entry) {
|
|
220
|
+
entry.spawning++;
|
|
221
|
+
const id = `${entry.key}-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
|
222
|
+
const internal = {
|
|
223
|
+
id,
|
|
224
|
+
serverKey: entry.key,
|
|
225
|
+
busy: false,
|
|
226
|
+
idleTimer: null,
|
|
227
|
+
pending: new Map(),
|
|
228
|
+
nextRequestId: 1,
|
|
229
|
+
lineBuffer: '',
|
|
230
|
+
writeLine: null,
|
|
231
|
+
close: () => { },
|
|
232
|
+
closed: false,
|
|
233
|
+
createdAt: Date.now(),
|
|
234
|
+
};
|
|
235
|
+
return new Promise((resolve, reject) => {
|
|
236
|
+
let resolved = false;
|
|
237
|
+
const transport = entry.factory({
|
|
238
|
+
onLine: (line) => this._handleLine(internal, line),
|
|
239
|
+
onClose: () => this._handleClose(entry, internal),
|
|
240
|
+
onError: (err) => {
|
|
241
|
+
if (!resolved) {
|
|
242
|
+
resolved = true;
|
|
243
|
+
entry.spawning--;
|
|
244
|
+
entry.connections.delete(id);
|
|
245
|
+
reject(err);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
this._handleError(entry, internal, err);
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
});
|
|
252
|
+
internal.writeLine = transport.write;
|
|
253
|
+
internal.close = transport.close;
|
|
254
|
+
entry.connections.set(id, internal);
|
|
255
|
+
entry.spawning--;
|
|
256
|
+
resolved = true;
|
|
257
|
+
logger.debug('ConnectionPool: spawned connection', { id, server: entry.key });
|
|
258
|
+
resolve(internal);
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
_handleLine(conn, raw) {
|
|
262
|
+
// Accumulate partial lines
|
|
263
|
+
conn.lineBuffer += raw;
|
|
264
|
+
// Process all complete newline-terminated JSON objects
|
|
265
|
+
let nl;
|
|
266
|
+
while ((nl = conn.lineBuffer.indexOf('\n')) !== -1) {
|
|
267
|
+
const line = conn.lineBuffer.slice(0, nl).trim();
|
|
268
|
+
conn.lineBuffer = conn.lineBuffer.slice(nl + 1);
|
|
269
|
+
if (!line)
|
|
270
|
+
continue;
|
|
271
|
+
let msg;
|
|
272
|
+
try {
|
|
273
|
+
msg = JSON.parse(line);
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
logger.warn('ConnectionPool: unparseable line from backend', { conn: conn.id, line: line.slice(0, 200) });
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
if (msg.id !== undefined) {
|
|
280
|
+
const pending = conn.pending.get(msg.id);
|
|
281
|
+
if (pending) {
|
|
282
|
+
conn.pending.delete(msg.id);
|
|
283
|
+
if (msg.error) {
|
|
284
|
+
pending.reject(new Error(msg.error.message ?? 'RPC error'));
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
pending.resolve(msg.result);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
_handleClose(entry, conn) {
|
|
294
|
+
if (conn.closed)
|
|
295
|
+
return;
|
|
296
|
+
conn.closed = true;
|
|
297
|
+
conn.writeLine = null;
|
|
298
|
+
// Reject all in-flight calls
|
|
299
|
+
for (const [, pending] of conn.pending) {
|
|
300
|
+
pending.reject(new Error(`Connection ${conn.id} to "${entry.key}" closed unexpectedly`));
|
|
301
|
+
}
|
|
302
|
+
conn.pending.clear();
|
|
303
|
+
if (conn.idleTimer) {
|
|
304
|
+
clearTimeout(conn.idleTimer);
|
|
305
|
+
conn.idleTimer = null;
|
|
306
|
+
}
|
|
307
|
+
entry.connections.delete(conn.id);
|
|
308
|
+
logger.warn('ConnectionPool: connection closed', { id: conn.id, server: entry.key });
|
|
309
|
+
if (this.isShuttingDown)
|
|
310
|
+
return;
|
|
311
|
+
// Respawn to maintain minimum floor
|
|
312
|
+
const activeCount = entry.connections.size + entry.spawning;
|
|
313
|
+
if (activeCount < this.opts.minConnectionsPerServer) {
|
|
314
|
+
setTimeout(() => {
|
|
315
|
+
if (!this.isShuttingDown) {
|
|
316
|
+
this._spawnConnection(entry)
|
|
317
|
+
.then((newConn) => {
|
|
318
|
+
logger.info('ConnectionPool: respawned connection after crash', {
|
|
319
|
+
newId: newConn.id,
|
|
320
|
+
server: entry.key,
|
|
321
|
+
});
|
|
322
|
+
// Drain any waiters that accumulated during the crash
|
|
323
|
+
this._drainWaiters(entry);
|
|
324
|
+
})
|
|
325
|
+
.catch((err) => {
|
|
326
|
+
logger.error('ConnectionPool: respawn failed', { server: entry.key, err: String(err) });
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
}, 0).unref?.();
|
|
330
|
+
}
|
|
331
|
+
this.emit('connectionClosed', entry.key, conn.id);
|
|
332
|
+
}
|
|
333
|
+
_handleError(entry, conn, err) {
|
|
334
|
+
logger.error('ConnectionPool: connection error', { id: conn.id, server: entry.key, err: err.message });
|
|
335
|
+
this._handleClose(entry, conn);
|
|
336
|
+
}
|
|
337
|
+
_startIdleTimer(entry, conn) {
|
|
338
|
+
if (conn.idleTimer)
|
|
339
|
+
clearTimeout(conn.idleTimer);
|
|
340
|
+
conn.idleTimer = setTimeout(() => {
|
|
341
|
+
const currentCount = entry.connections.size;
|
|
342
|
+
if (!conn.busy && currentCount > this.opts.minConnectionsPerServer) {
|
|
343
|
+
logger.debug('ConnectionPool: closing idle connection', { id: conn.id, server: entry.key });
|
|
344
|
+
this._closeInternal(conn);
|
|
345
|
+
entry.connections.delete(conn.id);
|
|
346
|
+
}
|
|
347
|
+
}, this.opts.idleTimeoutMs);
|
|
348
|
+
// Do not block Node.js exit for idle timers
|
|
349
|
+
if (conn.idleTimer.unref)
|
|
350
|
+
conn.idleTimer.unref();
|
|
351
|
+
}
|
|
352
|
+
_closeInternal(conn) {
|
|
353
|
+
if (conn.closed)
|
|
354
|
+
return;
|
|
355
|
+
conn.closed = true;
|
|
356
|
+
conn.writeLine = null;
|
|
357
|
+
for (const [, pending] of conn.pending) {
|
|
358
|
+
pending.reject(new Error(`Connection ${conn.id} closed`));
|
|
359
|
+
}
|
|
360
|
+
conn.pending.clear();
|
|
361
|
+
if (conn.idleTimer) {
|
|
362
|
+
clearTimeout(conn.idleTimer);
|
|
363
|
+
conn.idleTimer = null;
|
|
364
|
+
}
|
|
365
|
+
try {
|
|
366
|
+
conn.close();
|
|
367
|
+
}
|
|
368
|
+
catch {
|
|
369
|
+
// Ignore close errors
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
_drainWaiters(entry) {
|
|
373
|
+
while (entry.waiting.length > 0) {
|
|
374
|
+
const idle = this._findIdle(entry);
|
|
375
|
+
if (!idle)
|
|
376
|
+
break;
|
|
377
|
+
const waiter = entry.waiting.shift();
|
|
378
|
+
clearTimeout(waiter.timer);
|
|
379
|
+
idle.busy = true;
|
|
380
|
+
waiter.resolve(this._toPublic(idle));
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
//# sourceMappingURL=pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool.js","sourceRoot":"","sources":["../../src/bridge/pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CacheLayer — three-tier cache composition (memory LRU + disk CBOR + delta).
|
|
3
|
+
*
|
|
4
|
+
* Call flow:
|
|
5
|
+
* get(server, tool, args)
|
|
6
|
+
* → memory LRU hit? → return CacheHit (source: 'memory')
|
|
7
|
+
* → disk hit? → promote to memory, return CacheHit (source: 'disk')
|
|
8
|
+
* → miss → return null (caller must fetch from backend)
|
|
9
|
+
*
|
|
10
|
+
* Stale-while-revalidate (SWR):
|
|
11
|
+
* All staleness decisions are made here, not in DiskCache, so that
|
|
12
|
+
* vi.useFakeTimers() in tests correctly affects TTL checks at all tiers.
|
|
13
|
+
*
|
|
14
|
+
* Bridge wiring order (per spec):
|
|
15
|
+
* cache check → cache miss → reliability gateway (Agent C) → backend
|
|
16
|
+
*
|
|
17
|
+
* @module cache/cache
|
|
18
|
+
*/
|
|
19
|
+
import type { CacheHit, CacheStats, CacheLayerOptions, DeltaResult } from './index.js';
|
|
20
|
+
export interface ExtendedCacheHit extends CacheHit {
|
|
21
|
+
needsRevalidation?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare class CacheLayer {
|
|
24
|
+
private lru;
|
|
25
|
+
private disk;
|
|
26
|
+
private registry;
|
|
27
|
+
private options;
|
|
28
|
+
private unsubscribe;
|
|
29
|
+
private diskMisses;
|
|
30
|
+
private ttlMap;
|
|
31
|
+
constructor(options: CacheLayerOptions);
|
|
32
|
+
get(server: string, tool: string, args: unknown): Promise<ExtendedCacheHit | null>;
|
|
33
|
+
set(server: string, tool: string, args: unknown, result: unknown, options?: {
|
|
34
|
+
ttl?: number;
|
|
35
|
+
}): Promise<void>;
|
|
36
|
+
invalidate(server: string, pattern?: string): Promise<number>;
|
|
37
|
+
delta(server: string, tool: string, args: unknown, current: unknown): Promise<DeltaResult>;
|
|
38
|
+
stats(): CacheStats;
|
|
39
|
+
clear(): Promise<void>;
|
|
40
|
+
wouldCache(server: string, tool: string): boolean;
|
|
41
|
+
destroy(): void;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/cache/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAUH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEvF,MAAM,WAAW,gBAAiB,SAAQ,QAAQ;IAChD,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,IAAI,CAAY;IACxB,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,MAAM,CAA6B;gBAE/B,OAAO,EAAE,iBAAiB;IAgChC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAsDlF,GAAG,CACP,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,OAAO,EACf,OAAO,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GACzB,OAAO,CAAC,IAAI,CAAC;IAkBV,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAO7D,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC;IAMhG,KAAK,IAAI,UAAU;IAab,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5B,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAKjD,OAAO,IAAI,IAAI;CAMhB"}
|