@kb-labs/mcp-app 2.117.0 → 2.118.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.
Files changed (3) hide show
  1. package/dist/bin.cjs +1367 -2162
  2. package/dist/bin.cjs.map +1 -1
  3. package/package.json +17 -17
package/dist/bin.cjs CHANGED
@@ -3590,6 +3590,52 @@ function createSocketPath(id) {
3590
3590
  }
3591
3591
  return `/tmp/kb-${id}.sock`;
3592
3592
  }
3593
+ function createDocumentDatabaseProxy(transport) {
3594
+ return new DocumentDatabaseProxy(transport);
3595
+ }
3596
+ function createKVStoreProxy(transport) {
3597
+ return new KVStoreProxy(transport);
3598
+ }
3599
+ function createCacheProxy(transport) {
3600
+ return new CacheProxy(transport);
3601
+ }
3602
+ function createConfigProxy(transport) {
3603
+ return new ConfigProxy(transport);
3604
+ }
3605
+ function createVectorStoreProxy(transport) {
3606
+ return new VectorStoreProxy(transport);
3607
+ }
3608
+ function createInvokeProxy(transport) {
3609
+ return new InvokeProxy(transport);
3610
+ }
3611
+ function defineIPCOperations() {
3612
+ return (operations) => operations;
3613
+ }
3614
+ function createIPCAdapterRoutes() {
3615
+ const routes = {};
3616
+ for (const slot of Object.keys(platformAdapterTransportPolicy)) {
3617
+ const policy = platformAdapterTransportPolicy[slot];
3618
+ if (!("adapter" in policy)) {
3619
+ continue;
3620
+ }
3621
+ if (routes[policy.adapter] !== void 0) {
3622
+ throw new Error(`Duplicate IPC adapter route '${policy.adapter}'`);
3623
+ }
3624
+ routes[policy.adapter] = slot;
3625
+ }
3626
+ return Object.freeze(routes);
3627
+ }
3628
+ function resolveIPCAdapter(platform2, adapterType) {
3629
+ const slot = IPC_ADAPTER_ROUTES[adapterType];
3630
+ if (!slot) {
3631
+ throw new Error(`Adapter '${adapterType}' is not exposed over IPC`);
3632
+ }
3633
+ const adapter = platform2[slot];
3634
+ if (adapter === void 0) {
3635
+ throw new Error(`Adapter '${adapterType}' is not configured for IPC`);
3636
+ }
3637
+ return adapter;
3638
+ }
3593
3639
  function toSerializableError(error2) {
3594
3640
  const serialized = serialize(error2);
3595
3641
  if (serialized && typeof serialized === "object" && "__type" in serialized && serialized.__type === "Error") {
@@ -3650,14 +3696,14 @@ function createProxyPlatform(options) {
3650
3696
  const { transport } = options;
3651
3697
  const logger2 = options.logger ?? new LoggerProxy(transport);
3652
3698
  const processExecutor = new ProcessExecutorProxy(transport);
3653
- const cache = new CacheProxy(transport);
3699
+ const cache = platformAdapterTransportPolicy.cache.proxy(transport);
3654
3700
  const llm = new LLMProxy(transport);
3655
3701
  const embeddings = new EmbeddingsProxy(transport);
3656
- const vectorStore = new VectorStoreProxy(transport);
3702
+ const vectorStore = platformAdapterTransportPolicy.vectorStore.proxy(transport);
3657
3703
  const storage = new StorageProxy(transport);
3658
- const documentDatabase = new DocumentDatabaseProxy(transport);
3659
- const kvStore = new KVStoreProxy(transport);
3660
- const config2 = new ConfigProxy(transport);
3704
+ const documentDatabase = platformAdapterTransportPolicy.documentDatabase.proxy(transport);
3705
+ const kvStore = platformAdapterTransportPolicy.kvStore.proxy(transport);
3706
+ const config2 = platformAdapterTransportPolicy.config.proxy(transport);
3661
3707
  const eventBus = new EventBusProxy(transport);
3662
3708
  const analytics = {
3663
3709
  track: async () => {
@@ -3667,10 +3713,7 @@ function createProxyPlatform(options) {
3667
3713
  flush: async () => {
3668
3714
  }
3669
3715
  };
3670
- const invoke = {
3671
- call: async () => ({ success: false, error: "Invoke not available in proxy context" }),
3672
- isAvailable: async () => false
3673
- };
3716
+ const invoke = platformAdapterTransportPolicy.invoke.proxy(transport);
3674
3717
  const logs = {
3675
3718
  query: async () => ({ logs: [], total: 0, hasMore: false, source: "buffer" }),
3676
3719
  getById: async () => null,
@@ -3697,7 +3740,7 @@ function createProxyPlatform(options) {
3697
3740
  processExecutor
3698
3741
  };
3699
3742
  }
3700
- var BulkTransferHelper, DEFAULT_SOCKET_PATH, UnixSocketServer, IPCServer, ChildIPCServer, TransportError, TimeoutError, CircuitOpenError, OPERATION_TIMEOUTS, IPCTransport, UnixSocketTransport, RemoteAdapter, CacheProxy, LLMProxy, EmbeddingsProxy, VectorStoreProxy, StorageProxy, DocumentDatabaseProxy, stripSignal, KVStoreProxy, stripSignal2, ConfigProxy, EventBusProxy, LoggerProxy, PROCESS_RPC_GRACE_MS, CONTROL_RPC_TIMEOUT_MS, MAX_TIMER_MS, ProcessExecutorProxy;
3743
+ var BulkTransferHelper, DEFAULT_SOCKET_PATH, RemoteAdapter, DocumentDatabaseProxy, stripSignal, KVStoreProxy, stripSignal2, CacheProxy, ConfigProxy, VectorStoreProxy, InvokeProxy, documentDatabaseIPCOperations, kvStoreIPCOperations, cacheIPCOperations, configIPCOperations, vectorStoreIPCOperations, invokeIPCOperations, platformAdapterTransportPolicy, IPC_ADAPTER_ROUTES, UnixSocketServer, IPCServer, ChildIPCServer, TransportError, TimeoutError, CircuitOpenError, OPERATION_TIMEOUTS, IPCTransport, UnixSocketTransport, LLMProxy, EmbeddingsProxy, StorageProxy, EventBusProxy, LoggerProxy, PROCESS_RPC_GRACE_MS, CONTROL_RPC_TIMEOUT_MS, MAX_TIMER_MS, ProcessExecutorProxy;
3701
3744
  var init_dist5 = __esm({
3702
3745
  "../../../core/ipc/dist/index.js"() {
3703
3746
  init_serializable();
@@ -3814,300 +3857,881 @@ var init_dist5 = __esm({
3814
3857
  }
3815
3858
  });
3816
3859
  DEFAULT_SOCKET_PATH = createSocketPath(`ipc-${process.pid}`);
3817
- UnixSocketServer = class {
3860
+ RemoteAdapter = class {
3818
3861
  /**
3819
- * Create a Unix Socket server.
3862
+ * Create a remote adapter proxy.
3820
3863
  *
3821
- * @param platform - Platform container with real adapters
3822
- * @param config - Server configuration
3823
- */
3824
- constructor(platform2, config2 = {}) {
3825
- this.platform = platform2;
3826
- this.socketPath = config2.socketPath ?? DEFAULT_SOCKET_PATH;
3827
- this.authToken = config2.authToken;
3828
- }
3829
- platform;
3830
- server = null;
3831
- clients = /* @__PURE__ */ new Set();
3832
- socketPath;
3833
- authToken;
3834
- started = false;
3835
- /**
3836
- * Get the socket path.
3837
- * Used by parent process to pass to child processes via env var.
3864
+ * @param adapterName - Name of the adapter (e.g., 'vectorStore', 'cache')
3865
+ * @param transport - Transport layer for IPC communication
3866
+ * @param context - Optional execution context for tracing/debugging
3838
3867
  */
3839
- getSocketPath() {
3840
- return this.socketPath;
3868
+ constructor(adapterName, transport, context) {
3869
+ this.adapterName = adapterName;
3870
+ this.transport = transport;
3871
+ this.context = context;
3841
3872
  }
3873
+ adapterName;
3874
+ transport;
3875
+ context;
3842
3876
  /**
3843
- * Start listening for connections.
3877
+ * Set execution context for this adapter.
3878
+ * Context is included in all subsequent adapter calls for tracing/debugging.
3879
+ *
3880
+ * @param context - Execution context (traceId, pluginId, sessionId, etc.)
3881
+ *
3882
+ * @example
3883
+ * ```typescript
3884
+ * proxy.setContext({
3885
+ * traceId: 'trace-abc',
3886
+ * pluginId: '@kb-labs/mind',
3887
+ * sessionId: 'session-xyz',
3888
+ * });
3889
+ * ```
3844
3890
  */
3845
- async start() {
3846
- BulkTransferHelper.registerSignalHandlers();
3847
- if (fs5__namespace.existsSync(this.socketPath)) {
3848
- fs5__namespace.unlinkSync(this.socketPath);
3849
- }
3850
- return new Promise((resolve9, reject) => {
3851
- this.server = net__namespace.createServer((socket) => {
3852
- this.handleClient(socket);
3853
- });
3854
- this.server.on("error", (error2) => {
3855
- reject(error2);
3856
- });
3857
- this.server.listen(this.socketPath, () => {
3858
- fs5__namespace.chmodSync(this.socketPath, 438);
3859
- this.started = true;
3860
- this.platform.logger.debug("UnixSocketServer started listening for adapter calls");
3861
- resolve9();
3862
- });
3863
- });
3891
+ setContext(context) {
3892
+ this.context = context;
3864
3893
  }
3865
3894
  /**
3866
- * Handle new client connection.
3895
+ * Get current execution context.
3867
3896
  */
3868
- handleClient(socket) {
3869
- this.clients.add(socket);
3870
- let buffer = "";
3871
- socket.on("data", (data) => {
3872
- buffer += data.toString("utf8");
3873
- let newlineIndex;
3874
- while ((newlineIndex = buffer.indexOf("\n")) !== -1) {
3875
- const line = buffer.slice(0, newlineIndex);
3876
- buffer = buffer.slice(newlineIndex + 1);
3877
- if (line.trim().length === 0) {
3878
- continue;
3879
- }
3880
- try {
3881
- const call = JSON.parse(line);
3882
- this.handleCall(socket, call);
3883
- } catch (error2) {
3884
- this.platform.logger.warn("UnixSocketServer: failed to parse message", { error: error2 });
3885
- }
3886
- }
3887
- });
3888
- socket.on("close", () => {
3889
- this.clients.delete(socket);
3890
- });
3891
- socket.on("error", (error2) => {
3892
- this.platform.logger.warn("UnixSocketServer: client socket error", { error: error2 });
3893
- this.clients.delete(socket);
3894
- });
3897
+ getContext() {
3898
+ return this.context;
3895
3899
  }
3896
3900
  /**
3897
- * Handle adapter call from client.
3901
+ * Call a method on the remote adapter (in parent process).
3902
+ *
3903
+ * This method:
3904
+ * 1. Generates a unique request ID
3905
+ * 2. Serializes the method arguments
3906
+ * 3. Sends the call via transport
3907
+ * 4. Waits for response
3908
+ * 5. Deserializes and returns the result (or throws error)
3909
+ *
3910
+ * @param method - Method name to call on the adapter
3911
+ * @param args - Method arguments (will be serialized)
3912
+ * @param timeout - Optional timeout in milliseconds (overrides transport default)
3913
+ * @returns Promise resolving to deserialized result
3914
+ * @throws Error if remote method throws or communication fails
3915
+ *
3916
+ * @example
3917
+ * ```typescript
3918
+ * // In VectorStoreProxy.search():
3919
+ * return this.callRemote('search', [query, limit, filter]);
3920
+ *
3921
+ * // With custom timeout for bulk operations:
3922
+ * return this.callRemote('upsert', [vectors], 120000); // 2 min timeout
3923
+ * ```
3898
3924
  */
3899
- async handleCall(socket, call) {
3900
- const callAuthToken = call.context?.authToken;
3901
- if (this.authToken && callAuthToken !== this.authToken) {
3902
- const response = {
3903
- type: "adapter:response",
3904
- requestId: call.requestId,
3905
- error: toSerializableError(new Error("Unauthorized IPC call: invalid auth token"))
3906
- };
3907
- socket.write(JSON.stringify(response) + "\n", "utf8");
3908
- return;
3909
- }
3910
- if (call.version !== IPC_PROTOCOL_VERSION) {
3911
- this.platform.logger.warn("UnixSocketServer: protocol version mismatch", {
3912
- received: call.version,
3913
- expected: IPC_PROTOCOL_VERSION,
3914
- adapter: call.adapter,
3915
- method: call.method,
3916
- note: "Child process may be using outdated protocol. Consider rebuilding."
3917
- });
3925
+ async callRemote(method, args, timeout) {
3926
+ const requestId = crypto4.randomUUID();
3927
+ const call = {
3928
+ version: IPC_PROTOCOL_VERSION,
3929
+ // Protocol version for backward compatibility
3930
+ type: "adapter:call",
3931
+ requestId,
3932
+ adapter: this.adapterName,
3933
+ method,
3934
+ args: args.map((arg) => serialize(arg)),
3935
+ timeout,
3936
+ // Optional timeout for this specific call
3937
+ context: this.context
3938
+ // Include execution context for tracing/debugging
3939
+ };
3940
+ const response = await this.transport.send(call);
3941
+ if (response.error) {
3942
+ throw deserialize(response.error);
3918
3943
  }
3919
- if (call.context) {
3920
- this.platform.logger.debug("UnixSocketServer: adapter call", {
3921
- version: call.version,
3922
- traceId: call.context.traceId,
3923
- pluginId: call.context.pluginId,
3924
- sessionId: call.context.sessionId,
3925
- tenantId: call.context.tenantId,
3926
- adapter: call.adapter,
3927
- method: call.method
3928
- });
3944
+ if (response.result === void 0) {
3945
+ return void 0;
3929
3946
  }
3930
- try {
3931
- const adapter = this.getAdapter(call.adapter);
3932
- if (adapter === null || typeof adapter !== "object" && typeof adapter !== "function") {
3933
- throw new Error(`Adapter '${call.adapter}' is not callable`);
3934
- }
3935
- const method = Reflect.get(adapter, call.method);
3936
- if (typeof method !== "function") {
3937
- throw new Error(
3938
- `Method '${call.method}' not found on adapter '${call.adapter}'. Available methods: ${Object.getOwnPropertyNames(Object.getPrototypeOf(adapter)).join(", ")}`
3939
- );
3940
- }
3941
- const args = await Promise.all(
3942
- call.args.map(async (arg) => {
3943
- const deserialized = deserialize(arg);
3944
- if (BulkTransferHelper.isBulkTransfer(deserialized)) {
3945
- return BulkTransferHelper.deserialize(deserialized);
3946
- }
3947
- return deserialized;
3948
- })
3949
- );
3950
- const result = await method.apply(adapter, args);
3951
- let serializedResult;
3952
- if (result !== void 0 && result !== null && typeof result === "object") {
3953
- const resultJson = JSON.stringify(result);
3954
- if (resultJson.length > 1e6) {
3955
- const transfer = await BulkTransferHelper.serialize(result, {
3956
- maxInlineSize: 1e6,
3957
- tempDir: process.env.KB_TEMP_DIR ?? os4__namespace.tmpdir()
3958
- });
3959
- serializedResult = serialize(transfer);
3960
- } else {
3961
- serializedResult = serialize(result);
3962
- }
3963
- } else {
3964
- serializedResult = serialize(result);
3965
- }
3966
- const response = {
3967
- type: "adapter:response",
3968
- requestId: call.requestId,
3969
- result: serializedResult
3970
- };
3971
- const message2 = JSON.stringify(response) + "\n";
3972
- socket.write(message2, "utf8");
3973
- } catch (error2) {
3974
- const response = {
3975
- type: "adapter:response",
3976
- requestId: call.requestId,
3977
- error: toSerializableError(error2)
3978
- };
3979
- const message2 = JSON.stringify(response) + "\n";
3980
- socket.write(message2, "utf8");
3981
- const cause = error2 instanceof Error ? error2.message : String(error2);
3982
- this.platform.logger.error(
3983
- `UnixSocketServer: ${call.adapter}.${call.method} failed \u2014 ${cause}`,
3984
- error2 instanceof Error ? error2 : new Error(String(error2)),
3985
- { adapter: call.adapter, method: call.method }
3986
- );
3947
+ const result = deserialize(response.result);
3948
+ if (BulkTransferHelper.isBulkTransfer(result)) {
3949
+ return BulkTransferHelper.deserialize(result);
3987
3950
  }
3951
+ return result;
3988
3952
  }
3989
3953
  /**
3990
- * Get adapter instance from platform container.
3991
- *
3992
- * @param name - Adapter name (e.g., 'vectorStore', 'cache')
3993
- * @returns Adapter instance
3994
- * @throws Error if adapter not found
3954
+ * Get the adapter name this proxy represents.
3995
3955
  */
3996
- getAdapter(name) {
3997
- switch (name) {
3998
- case "vectorStore":
3999
- return this.platform.vectorStore;
4000
- case "cache":
4001
- return this.platform.cache;
4002
- case "config":
4003
- return this.platform.config;
4004
- case "llm":
4005
- return this.platform.llm;
4006
- case "embeddings":
4007
- return this.platform.embeddings;
4008
- case "storage":
4009
- return this.platform.storage;
4010
- case "logger":
4011
- return this.platform.logger;
4012
- case "analytics":
4013
- return this.platform.analytics;
4014
- case "eventBus":
4015
- return this.platform.eventBus;
4016
- case "processExecutor":
4017
- if (!this.platform.processExecutor) {
4018
- throw new Error("Governed process executor is not configured on execution host");
4019
- }
4020
- return this.platform.processExecutor;
4021
- case "invoke":
4022
- return this.platform.invoke;
4023
- default:
4024
- throw new Error(
4025
- `Unknown adapter: '${name}'. Valid adapters: vectorStore, cache, config, llm, embeddings, storage, logger, analytics, eventBus, invoke, processExecutor`
4026
- );
4027
- }
3956
+ getAdapterName() {
3957
+ return this.adapterName;
4028
3958
  }
4029
3959
  /**
4030
- * Stop server and close all connections.
3960
+ * Get the transport used by this proxy.
3961
+ * Useful for advanced use cases (e.g., checking if transport is closed).
4031
3962
  */
4032
- async close() {
4033
- if (!this.started) {
4034
- return;
4035
- }
4036
- for (const client of this.clients) {
4037
- client.destroy();
4038
- }
4039
- this.clients.clear();
4040
- if (this.server) {
4041
- await new Promise((resolve9) => {
4042
- this.server.close(() => {
4043
- resolve9();
4044
- });
4045
- });
4046
- this.server = null;
4047
- }
4048
- if (fs5__namespace.existsSync(this.socketPath)) {
4049
- fs5__namespace.unlinkSync(this.socketPath);
4050
- }
4051
- this.started = false;
4052
- this.platform.logger.debug("UnixSocketServer stopped listening for adapter calls");
3963
+ getTransport() {
3964
+ return this.transport;
3965
+ }
3966
+ };
3967
+ DocumentDatabaseProxy = class extends RemoteAdapter {
3968
+ constructor(transport) {
3969
+ super("database.document", transport);
3970
+ }
3971
+ async find(collection, filter2, options) {
3972
+ return await this.callRemote("find", [collection, filter2, stripSignal(options)]);
3973
+ }
3974
+ // eslint-disable-next-line require-yield
3975
+ async *findStream(_collection, _filter, _options) {
3976
+ throw new Error(
3977
+ "findStream() is not supported over IPC. Use bounded find({ limit }) and paginate explicitly."
3978
+ );
3979
+ }
3980
+ async findById(collection, id, _options) {
3981
+ return await this.callRemote("findById", [collection, id]);
3982
+ }
3983
+ async count(collection, filter2, _options) {
3984
+ return await this.callRemote("count", [collection, filter2]);
3985
+ }
3986
+ async insertOne(collection, doc, _options) {
3987
+ return await this.callRemote("insertOne", [collection, doc]);
3988
+ }
3989
+ async insertMany(collection, docs, _options) {
3990
+ return await this.callRemote("insertMany", [collection, docs]);
3991
+ }
3992
+ async updateOne(collection, filter2, update, options) {
3993
+ return await this.callRemote("updateOne", [
3994
+ collection,
3995
+ filter2,
3996
+ update,
3997
+ { upsert: options?.upsert }
3998
+ ]);
3999
+ }
4000
+ async updateMany(collection, filter2, update, _options) {
4001
+ return await this.callRemote("updateMany", [collection, filter2, update]);
4002
+ }
4003
+ async updateById(collection, id, update, _options) {
4004
+ return await this.callRemote("updateById", [collection, id, update]);
4005
+ }
4006
+ async deleteMany(collection, filter2, _options) {
4007
+ return await this.callRemote("deleteMany", [collection, filter2]);
4008
+ }
4009
+ async deleteById(collection, id, _options) {
4010
+ return await this.callRemote("deleteById", [collection, id]);
4011
+ }
4012
+ async bulkWrite(collection, ops, _options) {
4013
+ return await this.callRemote("bulkWrite", [collection, ops]);
4014
+ }
4015
+ async transaction(_fn) {
4016
+ throw new Error(
4017
+ "transaction() is not supported over IPC. Collect your writes into a single bulkWrite() instead."
4018
+ );
4019
+ }
4020
+ async ensureCollection(name, options) {
4021
+ await this.callRemote("ensureCollection", [name, options]);
4022
+ }
4023
+ async ping() {
4024
+ return await this.callRemote("ping", []);
4025
+ }
4026
+ async close(options) {
4027
+ await this.callRemote("close", [options]);
4028
+ }
4029
+ };
4030
+ stripSignal = (options) => {
4031
+ if (!options) {
4032
+ return void 0;
4033
+ }
4034
+ const { signal: _signal, ...rest } = options;
4035
+ return rest;
4036
+ };
4037
+ KVStoreProxy = class extends RemoteAdapter {
4038
+ constructor(transport) {
4039
+ super("database.kv", transport);
4040
+ }
4041
+ async get(key, _options) {
4042
+ return await this.callRemote("get", [key]);
4043
+ }
4044
+ async getMany(keys, _options) {
4045
+ return await this.callRemote("getMany", [keys]);
4046
+ }
4047
+ async set(key, value, options) {
4048
+ return await this.callRemote("set", [key, value, stripSignal2(options)]);
4049
+ }
4050
+ async setMany(entries, _options) {
4051
+ await this.callRemote("setMany", [entries]);
4052
+ }
4053
+ async setIfNotExists(key, value, options) {
4054
+ return await this.callRemote("setIfNotExists", [key, value, stripSignal2(options)]);
4055
+ }
4056
+ async delete(key, _options) {
4057
+ return await this.callRemote("delete", [key]);
4058
+ }
4059
+ async exists(key, _options) {
4060
+ return await this.callRemote("exists", [key]);
4061
+ }
4062
+ async cas(key, expected, next, options) {
4063
+ return await this.callRemote("cas", [key, expected, next, stripSignal2(options)]);
4064
+ }
4065
+ async incr(key, delta, options) {
4066
+ return await this.callRemote("incr", [key, delta, stripSignal2(options)]);
4067
+ }
4068
+ async ttl(key) {
4069
+ return await this.callRemote("ttl", [key]);
4070
+ }
4071
+ async expire(key, ttlMs) {
4072
+ return await this.callRemote("expire", [key, ttlMs]);
4073
+ }
4074
+ async persist(key) {
4075
+ return await this.callRemote("persist", [key]);
4076
+ }
4077
+ // eslint-disable-next-line require-yield
4078
+ async *scan(_prefix, _options) {
4079
+ throw new Error("scan() is not supported over IPC. Use bounded getMany() with an explicit key list.");
4080
+ }
4081
+ async ping() {
4082
+ return await this.callRemote("ping", []);
4083
+ }
4084
+ async close(options) {
4085
+ await this.callRemote("close", [options]);
4086
+ }
4087
+ };
4088
+ stripSignal2 = (options) => {
4089
+ if (!options) {
4090
+ return void 0;
4053
4091
  }
4092
+ const { signal: _signal, ...rest } = options;
4093
+ return rest;
4094
+ };
4095
+ CacheProxy = class extends RemoteAdapter {
4054
4096
  /**
4055
- * Check if server is started.
4097
+ * Create a cache proxy.
4098
+ *
4099
+ * @param transport - IPC transport to communicate with parent
4056
4100
  */
4057
- isStarted() {
4058
- return this.started;
4101
+ constructor(transport) {
4102
+ super("cache", transport);
4059
4103
  }
4060
- };
4061
- IPCServer = class {
4062
4104
  /**
4063
- * Create an IPC server.
4105
+ * Get a value from cache.
4064
4106
  *
4065
- * @param platform - Platform container with real adapters
4107
+ * @param key - Cache key
4108
+ * @returns Cached value or null if not found/expired
4066
4109
  */
4067
- constructor(platform2) {
4068
- this.platform = platform2;
4069
- this.messageHandler = this.handleMessage.bind(this);
4110
+ async get(key) {
4111
+ return await this.callRemote("get", [key]);
4070
4112
  }
4071
- platform;
4072
- messageHandler;
4073
- started = false;
4074
4113
  /**
4075
- * Start listening for IPC messages.
4114
+ * Set a value in cache.
4076
4115
  *
4077
- * Call this in the parent process (CLI bin) after initPlatform().
4078
- * The server will handle all adapter calls from child processes.
4116
+ * @param key - Cache key
4117
+ * @param value - Value to cache
4118
+ * @param ttl - Time to live in milliseconds (optional)
4119
+ */
4120
+ async set(key, value, ttl) {
4121
+ await this.callRemote("set", [key, value, ttl]);
4122
+ }
4123
+ /**
4124
+ * Delete a value from cache.
4079
4125
  *
4080
- * @throws Error if already started
4081
- * @throws Error if not running in parent process with IPC
4126
+ * @param key - Cache key
4082
4127
  */
4083
- start() {
4084
- if (this.started) {
4085
- throw new Error("IPCServer already started");
4086
- }
4087
- if (typeof process.on !== "function") {
4088
- throw new Error("IPCServer requires Node.js process object");
4089
- }
4090
- process.on("message", this.messageHandler);
4091
- this.started = true;
4092
- this.platform.logger.debug("IPCServer started listening for adapter calls");
4128
+ async delete(key) {
4129
+ await this.callRemote("delete", [key]);
4093
4130
  }
4094
4131
  /**
4095
- * Stop listening for IPC messages.
4132
+ * Clear cache entries matching a pattern.
4096
4133
  *
4097
- * Removes the message listener. Pending calls will not receive responses.
4134
+ * @param pattern - Glob pattern (e.g., 'user:*')
4098
4135
  */
4099
- stop() {
4100
- if (!this.started) {
4101
- return;
4102
- }
4103
- process.off("message", this.messageHandler);
4104
- this.started = false;
4105
- this.platform.logger.debug("IPCServer stopped listening for adapter calls");
4136
+ async clear(pattern) {
4137
+ await this.callRemote("clear", [pattern]);
4106
4138
  }
4107
4139
  /**
4108
- * Handle incoming IPC message.
4140
+ * Add member to sorted set with score.
4109
4141
  *
4110
- * Validates message format, executes adapter call, and sends response.
4142
+ * @param key - Sorted set key
4143
+ * @param score - Numeric score (typically timestamp)
4144
+ * @param member - Member to add
4145
+ */
4146
+ async zadd(key, score, member) {
4147
+ await this.callRemote("zadd", [key, score, member]);
4148
+ }
4149
+ /**
4150
+ * Get members from sorted set by score range.
4151
+ *
4152
+ * @param key - Sorted set key
4153
+ * @param min - Minimum score (inclusive)
4154
+ * @param max - Maximum score (inclusive)
4155
+ * @returns Array of members in score order
4156
+ */
4157
+ async zrangebyscore(key, min, max) {
4158
+ return await this.callRemote("zrangebyscore", [key, min, max]);
4159
+ }
4160
+ /**
4161
+ * Remove member from sorted set.
4162
+ *
4163
+ * @param key - Sorted set key
4164
+ * @param member - Member to remove
4165
+ */
4166
+ async zrem(key, member) {
4167
+ await this.callRemote("zrem", [key, member]);
4168
+ }
4169
+ /**
4170
+ * Set key-value pair only if key does not exist (atomic operation).
4171
+ *
4172
+ * @param key - Cache key
4173
+ * @param value - Value to set
4174
+ * @param ttl - Time to live in milliseconds (optional)
4175
+ * @returns true if value was set, false if key already exists
4176
+ */
4177
+ async setIfNotExists(key, value, ttl) {
4178
+ return await this.callRemote("setIfNotExists", [key, value, ttl]);
4179
+ }
4180
+ };
4181
+ ConfigProxy = class extends RemoteAdapter {
4182
+ /**
4183
+ * Create a config proxy.
4184
+ *
4185
+ * @param transport - IPC transport to communicate with parent
4186
+ */
4187
+ constructor(transport) {
4188
+ super("config", transport);
4189
+ }
4190
+ /**
4191
+ * Get product-specific configuration.
4192
+ *
4193
+ * @param productId - Product identifier (e.g., 'mind', 'workflow', 'plugins')
4194
+ * @param profileId - Profile identifier (defaults to 'default' or KB_PROFILE env var)
4195
+ * @returns Promise resolving to product-specific config or undefined
4196
+ *
4197
+ * @example
4198
+ * ```typescript
4199
+ * const mindConfig = await config.getConfig('mind');
4200
+ * if (mindConfig?.scopes) {
4201
+ * // Use scopes
4202
+ * }
4203
+ * ```
4204
+ */
4205
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4206
+ async getConfig(productId, profileId) {
4207
+ return this.callRemote("getConfig", [productId, profileId]);
4208
+ }
4209
+ /**
4210
+ * Get raw kb.config.json data.
4211
+ *
4212
+ * @returns Promise resolving to raw config object or undefined
4213
+ *
4214
+ * @example
4215
+ * ```typescript
4216
+ * const rawConfig = await config.getRawConfig();
4217
+ * if (rawConfig) {
4218
+ * const allProfiles = rawConfig.profiles;
4219
+ * }
4220
+ * ```
4221
+ */
4222
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4223
+ async getRawConfig() {
4224
+ return this.callRemote("getRawConfig", []);
4225
+ }
4226
+ };
4227
+ VectorStoreProxy = class _VectorStoreProxy extends RemoteAdapter {
4228
+ // Timeout for bulk operations that may trigger IPC backpressure
4229
+ static BULK_OPERATION_TIMEOUT = 12e4;
4230
+ // 2 minutes
4231
+ // BulkTransfer configuration
4232
+ bulkTransferOptions = {
4233
+ maxInlineSize: 1e6,
4234
+ // 1MB threshold
4235
+ tempDir: process.env.KB_TEMP_DIR ?? os4.tmpdir()
4236
+ };
4237
+ /**
4238
+ * Create a vector store proxy.
4239
+ *
4240
+ * @param transport - IPC transport to communicate with parent
4241
+ */
4242
+ constructor(transport) {
4243
+ super("vectorStore", transport);
4244
+ }
4245
+ /**
4246
+ * Search for similar vectors.
4247
+ *
4248
+ * @param query - Query embedding vector
4249
+ * @param limit - Maximum number of results
4250
+ * @param filter - Optional metadata filter
4251
+ * @returns Promise resolving to search results
4252
+ */
4253
+ async search(query, limit, filter2, namespace) {
4254
+ return await this.callRemote("search", [query, limit, filter2, namespace]);
4255
+ }
4256
+ /**
4257
+ * Insert or update vectors.
4258
+ * Uses BulkTransfer for large payloads to avoid IPC backpressure.
4259
+ *
4260
+ * @param vectors - Vector records to upsert
4261
+ */
4262
+ async upsert(vectors, namespace) {
4263
+ const transfer = await BulkTransferHelper.serialize(vectors, this.bulkTransferOptions);
4264
+ await this.callRemote("upsert", [transfer, namespace], _VectorStoreProxy.BULK_OPERATION_TIMEOUT);
4265
+ }
4266
+ /**
4267
+ * Delete vectors by IDs.
4268
+ * Uses extended timeout for bulk deletions.
4269
+ *
4270
+ * @param ids - Vector IDs to delete
4271
+ */
4272
+ async delete(ids, namespace) {
4273
+ await this.callRemote("delete", [ids, namespace], _VectorStoreProxy.BULK_OPERATION_TIMEOUT);
4274
+ }
4275
+ /**
4276
+ * Count total vectors in collection.
4277
+ *
4278
+ * @returns Promise resolving to vector count
4279
+ */
4280
+ async count(namespace) {
4281
+ return await this.callRemote("count", [namespace]);
4282
+ }
4283
+ /**
4284
+ * Get vectors by IDs.
4285
+ * IDs argument is usually small, passed directly through IPC.
4286
+ * Uses BulkTransfer only for large result sets.
4287
+ *
4288
+ * @param ids - Vector IDs to retrieve
4289
+ * @returns Promise resolving to vector records
4290
+ */
4291
+ async get(ids, namespace) {
4292
+ const resultTransfer = await this.callRemote("get", [ids, namespace], _VectorStoreProxy.BULK_OPERATION_TIMEOUT);
4293
+ if (BulkTransferHelper.isBulkTransfer(resultTransfer)) {
4294
+ return BulkTransferHelper.deserialize(resultTransfer);
4295
+ }
4296
+ return resultTransfer;
4297
+ }
4298
+ /**
4299
+ * Query vectors by metadata filter.
4300
+ * Filter argument is small, passed directly through IPC.
4301
+ * Uses BulkTransfer only for potentially large result sets.
4302
+ *
4303
+ * @param filter - Metadata filter to apply
4304
+ * @returns Promise resolving to matching vector records
4305
+ */
4306
+ async query(filter2, namespace) {
4307
+ const resultTransfer = await this.callRemote("query", [filter2, namespace], _VectorStoreProxy.BULK_OPERATION_TIMEOUT);
4308
+ if (BulkTransferHelper.isBulkTransfer(resultTransfer)) {
4309
+ return BulkTransferHelper.deserialize(resultTransfer);
4310
+ }
4311
+ return resultTransfer;
4312
+ }
4313
+ };
4314
+ InvokeProxy = class extends RemoteAdapter {
4315
+ constructor(transport) {
4316
+ super("invoke", transport);
4317
+ }
4318
+ async call(request) {
4319
+ return await this.callRemote("call", [request]);
4320
+ }
4321
+ async isAvailable(pluginId, command) {
4322
+ return await this.callRemote("isAvailable", [pluginId, command]);
4323
+ }
4324
+ };
4325
+ documentDatabaseIPCOperations = defineIPCOperations()({
4326
+ find: "unary",
4327
+ findStream: "stream",
4328
+ findById: "unary",
4329
+ count: "unary",
4330
+ insertOne: "unary",
4331
+ insertMany: "unary",
4332
+ updateOne: "unary",
4333
+ updateMany: "unary",
4334
+ updateById: "unary",
4335
+ deleteMany: "unary",
4336
+ deleteById: "unary",
4337
+ bulkWrite: "unary",
4338
+ transaction: "interactive",
4339
+ ensureCollection: "unary",
4340
+ ping: "unary",
4341
+ close: "unary"
4342
+ });
4343
+ kvStoreIPCOperations = defineIPCOperations()({
4344
+ get: "unary",
4345
+ getMany: "unary",
4346
+ set: "unary",
4347
+ setMany: "unary",
4348
+ setIfNotExists: "unary",
4349
+ delete: "unary",
4350
+ exists: "unary",
4351
+ cas: "unary",
4352
+ incr: "unary",
4353
+ ttl: "unary",
4354
+ expire: "unary",
4355
+ persist: "unary",
4356
+ scan: "stream",
4357
+ ping: "unary",
4358
+ close: "unary"
4359
+ });
4360
+ cacheIPCOperations = defineIPCOperations()({
4361
+ get: "unary",
4362
+ set: "unary",
4363
+ delete: "unary",
4364
+ clear: "unary",
4365
+ zadd: "unary",
4366
+ zrangebyscore: "unary",
4367
+ zrem: "unary",
4368
+ setIfNotExists: "unary"
4369
+ });
4370
+ configIPCOperations = defineIPCOperations()({
4371
+ getConfig: "unary",
4372
+ getRawConfig: "unary"
4373
+ });
4374
+ vectorStoreIPCOperations = defineIPCOperations()({
4375
+ search: "unary",
4376
+ upsert: "unary",
4377
+ delete: "unary",
4378
+ count: "unary",
4379
+ get: "unary",
4380
+ query: "unary"
4381
+ });
4382
+ invokeIPCOperations = defineIPCOperations()({
4383
+ call: "unary",
4384
+ isAvailable: "unary"
4385
+ });
4386
+ platformAdapterTransportPolicy = {
4387
+ logger: {
4388
+ mode: "migration",
4389
+ adapter: "logger",
4390
+ reason: "LoggerProxy is wired but still has fire-and-forget delivery semantics."
4391
+ },
4392
+ analytics: {
4393
+ mode: "migration",
4394
+ adapter: "analytics",
4395
+ reason: "Optional read and source-management operations need a capability-aware IPC design."
4396
+ },
4397
+ vectorStore: {
4398
+ mode: "ipc",
4399
+ adapter: "vectorStore",
4400
+ operations: vectorStoreIPCOperations,
4401
+ proxy: createVectorStoreProxy
4402
+ },
4403
+ llm: {
4404
+ mode: "migration",
4405
+ adapter: "llm",
4406
+ reason: "Streaming currently degrades to a completion over IPC."
4407
+ },
4408
+ embeddings: {
4409
+ mode: "migration",
4410
+ adapter: "embeddings",
4411
+ reason: "The dimensions property requires out-of-band initialization in the proxy."
4412
+ },
4413
+ cache: {
4414
+ mode: "ipc",
4415
+ adapter: "cache",
4416
+ operations: cacheIPCOperations,
4417
+ proxy: createCacheProxy
4418
+ },
4419
+ config: {
4420
+ mode: "ipc",
4421
+ adapter: "config",
4422
+ operations: configIPCOperations,
4423
+ proxy: createConfigProxy
4424
+ },
4425
+ storage: {
4426
+ mode: "migration",
4427
+ adapter: "storage",
4428
+ reason: "Node streams are not serializable over the current IPC protocol."
4429
+ },
4430
+ eventBus: {
4431
+ mode: "migration",
4432
+ adapter: "eventBus",
4433
+ reason: "Subscriptions use a dedicated push-message protocol."
4434
+ },
4435
+ invoke: {
4436
+ mode: "ipc",
4437
+ adapter: "invoke",
4438
+ operations: invokeIPCOperations,
4439
+ proxy: createInvokeProxy
4440
+ },
4441
+ documentDatabase: {
4442
+ mode: "ipc",
4443
+ adapter: "database.document",
4444
+ operations: documentDatabaseIPCOperations,
4445
+ proxy: createDocumentDatabaseProxy
4446
+ },
4447
+ kvStore: {
4448
+ mode: "ipc",
4449
+ adapter: "database.kv",
4450
+ operations: kvStoreIPCOperations,
4451
+ proxy: createKVStoreProxy
4452
+ },
4453
+ logs: {
4454
+ mode: "local-only",
4455
+ reason: "Log queries are intentionally unavailable to worker processes."
4456
+ },
4457
+ artifacts: {
4458
+ mode: "migration",
4459
+ adapter: "artifacts",
4460
+ reason: "Artifacts have a wire route but no worker proxy yet."
4461
+ },
4462
+ snapshotManager: {
4463
+ mode: "local-only",
4464
+ reason: "Snapshot lifecycle is owned by the execution host."
4465
+ },
4466
+ notifier: {
4467
+ mode: "local-only",
4468
+ reason: "Notifications are emitted by the host after worker execution."
4469
+ },
4470
+ processExecutor: {
4471
+ mode: "migration",
4472
+ adapter: "processExecutor",
4473
+ reason: "Existing proxy must be moved to a checked operation inventory."
4474
+ },
4475
+ serviceTransport: {
4476
+ mode: "local-only",
4477
+ reason: "Service transport is a platform-internal adapter and never enters plugin context."
4478
+ }
4479
+ };
4480
+ IPC_ADAPTER_ROUTES = createIPCAdapterRoutes();
4481
+ UnixSocketServer = class {
4482
+ /**
4483
+ * Create a Unix Socket server.
4484
+ *
4485
+ * @param platform - Platform container with real adapters
4486
+ * @param config - Server configuration
4487
+ */
4488
+ constructor(platform2, config2 = {}) {
4489
+ this.platform = platform2;
4490
+ this.socketPath = config2.socketPath ?? DEFAULT_SOCKET_PATH;
4491
+ this.authToken = config2.authToken;
4492
+ }
4493
+ platform;
4494
+ server = null;
4495
+ clients = /* @__PURE__ */ new Set();
4496
+ socketPath;
4497
+ authToken;
4498
+ started = false;
4499
+ /**
4500
+ * Get the socket path.
4501
+ * Used by parent process to pass to child processes via env var.
4502
+ */
4503
+ getSocketPath() {
4504
+ return this.socketPath;
4505
+ }
4506
+ /**
4507
+ * Start listening for connections.
4508
+ */
4509
+ async start() {
4510
+ BulkTransferHelper.registerSignalHandlers();
4511
+ if (fs5__namespace.existsSync(this.socketPath)) {
4512
+ fs5__namespace.unlinkSync(this.socketPath);
4513
+ }
4514
+ return new Promise((resolve9, reject) => {
4515
+ this.server = net__namespace.createServer((socket) => {
4516
+ this.handleClient(socket);
4517
+ });
4518
+ this.server.on("error", (error2) => {
4519
+ reject(error2);
4520
+ });
4521
+ this.server.listen(this.socketPath, () => {
4522
+ fs5__namespace.chmodSync(this.socketPath, 438);
4523
+ this.started = true;
4524
+ this.platform.logger.debug("UnixSocketServer started listening for adapter calls");
4525
+ resolve9();
4526
+ });
4527
+ });
4528
+ }
4529
+ /**
4530
+ * Handle new client connection.
4531
+ */
4532
+ handleClient(socket) {
4533
+ this.clients.add(socket);
4534
+ let buffer = "";
4535
+ socket.on("data", (data) => {
4536
+ buffer += data.toString("utf8");
4537
+ let newlineIndex;
4538
+ while ((newlineIndex = buffer.indexOf("\n")) !== -1) {
4539
+ const line = buffer.slice(0, newlineIndex);
4540
+ buffer = buffer.slice(newlineIndex + 1);
4541
+ if (line.trim().length === 0) {
4542
+ continue;
4543
+ }
4544
+ try {
4545
+ const call = JSON.parse(line);
4546
+ this.handleCall(socket, call);
4547
+ } catch (error2) {
4548
+ this.platform.logger.warn("UnixSocketServer: failed to parse message", { error: error2 });
4549
+ }
4550
+ }
4551
+ });
4552
+ socket.on("close", () => {
4553
+ this.clients.delete(socket);
4554
+ });
4555
+ socket.on("error", (error2) => {
4556
+ this.platform.logger.warn("UnixSocketServer: client socket error", { error: error2 });
4557
+ this.clients.delete(socket);
4558
+ });
4559
+ }
4560
+ /**
4561
+ * Handle adapter call from client.
4562
+ */
4563
+ async handleCall(socket, call) {
4564
+ const callAuthToken = call.context?.authToken;
4565
+ if (this.authToken && callAuthToken !== this.authToken) {
4566
+ const response = {
4567
+ type: "adapter:response",
4568
+ requestId: call.requestId,
4569
+ error: toSerializableError(new Error("Unauthorized IPC call: invalid auth token"))
4570
+ };
4571
+ socket.write(JSON.stringify(response) + "\n", "utf8");
4572
+ return;
4573
+ }
4574
+ if (call.version !== IPC_PROTOCOL_VERSION) {
4575
+ this.platform.logger.warn("UnixSocketServer: protocol version mismatch", {
4576
+ received: call.version,
4577
+ expected: IPC_PROTOCOL_VERSION,
4578
+ adapter: call.adapter,
4579
+ method: call.method,
4580
+ note: "Child process may be using outdated protocol. Consider rebuilding."
4581
+ });
4582
+ }
4583
+ if (call.context) {
4584
+ this.platform.logger.debug("UnixSocketServer: adapter call", {
4585
+ version: call.version,
4586
+ traceId: call.context.traceId,
4587
+ pluginId: call.context.pluginId,
4588
+ sessionId: call.context.sessionId,
4589
+ tenantId: call.context.tenantId,
4590
+ adapter: call.adapter,
4591
+ method: call.method
4592
+ });
4593
+ }
4594
+ try {
4595
+ const adapter = resolveIPCAdapter(this.platform, call.adapter);
4596
+ if (adapter === null || typeof adapter !== "object" && typeof adapter !== "function") {
4597
+ throw new Error(`Adapter '${call.adapter}' is not callable`);
4598
+ }
4599
+ const method = Reflect.get(adapter, call.method);
4600
+ if (typeof method !== "function") {
4601
+ throw new Error(
4602
+ `Method '${call.method}' not found on adapter '${call.adapter}'. Available methods: ${Object.getOwnPropertyNames(Object.getPrototypeOf(adapter)).join(", ")}`
4603
+ );
4604
+ }
4605
+ const args = await Promise.all(
4606
+ call.args.map(async (arg) => {
4607
+ const deserialized = deserialize(arg);
4608
+ if (BulkTransferHelper.isBulkTransfer(deserialized)) {
4609
+ return BulkTransferHelper.deserialize(deserialized);
4610
+ }
4611
+ return deserialized;
4612
+ })
4613
+ );
4614
+ const result = await method.apply(adapter, args);
4615
+ let serializedResult;
4616
+ if (result !== void 0 && result !== null && typeof result === "object") {
4617
+ const resultJson = JSON.stringify(result);
4618
+ if (resultJson.length > 1e6) {
4619
+ const transfer = await BulkTransferHelper.serialize(result, {
4620
+ maxInlineSize: 1e6,
4621
+ tempDir: process.env.KB_TEMP_DIR ?? os4__namespace.tmpdir()
4622
+ });
4623
+ serializedResult = serialize(transfer);
4624
+ } else {
4625
+ serializedResult = serialize(result);
4626
+ }
4627
+ } else {
4628
+ serializedResult = serialize(result);
4629
+ }
4630
+ const response = {
4631
+ type: "adapter:response",
4632
+ requestId: call.requestId,
4633
+ result: serializedResult
4634
+ };
4635
+ const message2 = JSON.stringify(response) + "\n";
4636
+ socket.write(message2, "utf8");
4637
+ } catch (error2) {
4638
+ const response = {
4639
+ type: "adapter:response",
4640
+ requestId: call.requestId,
4641
+ error: toSerializableError(error2)
4642
+ };
4643
+ const message2 = JSON.stringify(response) + "\n";
4644
+ socket.write(message2, "utf8");
4645
+ const cause = error2 instanceof Error ? error2.message : String(error2);
4646
+ this.platform.logger.error(
4647
+ `UnixSocketServer: ${call.adapter}.${call.method} failed \u2014 ${cause}`,
4648
+ error2 instanceof Error ? error2 : new Error(String(error2)),
4649
+ { adapter: call.adapter, method: call.method }
4650
+ );
4651
+ }
4652
+ }
4653
+ /**
4654
+ * Stop server and close all connections.
4655
+ */
4656
+ async close() {
4657
+ if (!this.started) {
4658
+ return;
4659
+ }
4660
+ for (const client of this.clients) {
4661
+ client.destroy();
4662
+ }
4663
+ this.clients.clear();
4664
+ if (this.server) {
4665
+ await new Promise((resolve9) => {
4666
+ this.server.close(() => {
4667
+ resolve9();
4668
+ });
4669
+ });
4670
+ this.server = null;
4671
+ }
4672
+ if (fs5__namespace.existsSync(this.socketPath)) {
4673
+ fs5__namespace.unlinkSync(this.socketPath);
4674
+ }
4675
+ this.started = false;
4676
+ this.platform.logger.debug("UnixSocketServer stopped listening for adapter calls");
4677
+ }
4678
+ /**
4679
+ * Check if server is started.
4680
+ */
4681
+ isStarted() {
4682
+ return this.started;
4683
+ }
4684
+ };
4685
+ IPCServer = class {
4686
+ /**
4687
+ * Create an IPC server.
4688
+ *
4689
+ * @param platform - Platform container with real adapters
4690
+ */
4691
+ constructor(platform2) {
4692
+ this.platform = platform2;
4693
+ this.messageHandler = this.handleMessage.bind(this);
4694
+ }
4695
+ platform;
4696
+ messageHandler;
4697
+ started = false;
4698
+ /**
4699
+ * Start listening for IPC messages.
4700
+ *
4701
+ * Call this in the parent process (CLI bin) after initPlatform().
4702
+ * The server will handle all adapter calls from child processes.
4703
+ *
4704
+ * @throws Error if already started
4705
+ * @throws Error if not running in parent process with IPC
4706
+ */
4707
+ start() {
4708
+ if (this.started) {
4709
+ throw new Error("IPCServer already started");
4710
+ }
4711
+ if (typeof process.on !== "function") {
4712
+ throw new Error("IPCServer requires Node.js process object");
4713
+ }
4714
+ process.on("message", this.messageHandler);
4715
+ this.started = true;
4716
+ this.platform.logger.debug("IPCServer started listening for adapter calls");
4717
+ }
4718
+ /**
4719
+ * Stop listening for IPC messages.
4720
+ *
4721
+ * Removes the message listener. Pending calls will not receive responses.
4722
+ */
4723
+ stop() {
4724
+ if (!this.started) {
4725
+ return;
4726
+ }
4727
+ process.off("message", this.messageHandler);
4728
+ this.started = false;
4729
+ this.platform.logger.debug("IPCServer stopped listening for adapter calls");
4730
+ }
4731
+ /**
4732
+ * Handle incoming IPC message.
4733
+ *
4734
+ * Validates message format, executes adapter call, and sends response.
4111
4735
  */
4112
4736
  async handleMessage(msg, sendHandle) {
4113
4737
  if (!isAdapterCall(msg)) {
@@ -4134,7 +4758,7 @@ var init_dist5 = __esm({
4134
4758
  });
4135
4759
  }
4136
4760
  try {
4137
- const adapter = this.getAdapter(msg.adapter);
4761
+ const adapter = resolveIPCAdapter(this.platform, msg.adapter);
4138
4762
  const method = adapter[msg.method];
4139
4763
  if (typeof method !== "function") {
4140
4764
  throw new Error(
@@ -4167,44 +4791,6 @@ var init_dist5 = __esm({
4167
4791
  );
4168
4792
  }
4169
4793
  }
4170
- /**
4171
- * Get adapter instance from platform container.
4172
- *
4173
- * @param name - Adapter name (e.g., 'vectorStore', 'cache')
4174
- * @returns Adapter instance
4175
- * @throws Error if adapter not found
4176
- */
4177
- getAdapter(name) {
4178
- switch (name) {
4179
- case "vectorStore":
4180
- return this.platform.vectorStore;
4181
- case "cache":
4182
- return this.platform.cache;
4183
- case "llm":
4184
- return this.platform.llm;
4185
- case "embeddings":
4186
- return this.platform.embeddings;
4187
- case "storage":
4188
- return this.platform.storage;
4189
- case "logger":
4190
- return this.platform.logger;
4191
- case "analytics":
4192
- return this.platform.analytics;
4193
- case "eventBus":
4194
- return this.platform.eventBus;
4195
- case "invoke":
4196
- return this.platform.invoke;
4197
- case "processExecutor":
4198
- if (!this.platform.processExecutor) {
4199
- throw new Error("Governed process executor is not configured on execution host");
4200
- }
4201
- return this.platform.processExecutor;
4202
- default:
4203
- throw new Error(
4204
- `Unknown adapter: '${name}'. Valid adapters: vectorStore, cache, llm, embeddings, storage, logger, analytics, eventBus, invoke, processExecutor`
4205
- );
4206
- }
4207
- }
4208
4794
  /**
4209
4795
  * Check if server is started.
4210
4796
  */
@@ -4292,7 +4878,7 @@ var init_dist5 = __esm({
4292
4878
  return;
4293
4879
  }
4294
4880
  try {
4295
- const adapter = this.getAdapter(msg.adapter);
4881
+ const adapter = resolveIPCAdapter(this.platform, msg.adapter);
4296
4882
  const method = adapter[msg.method];
4297
4883
  if (typeof method !== "function") {
4298
4884
  throw new Error(
@@ -4343,25 +4929,6 @@ var init_dist5 = __esm({
4343
4929
  this.child.send(response);
4344
4930
  }
4345
4931
  }
4346
- /**
4347
- * Get adapter from platform by name.
4348
- * Dynamic dispatch — no hardcoded switch; new adapters in IPlatformAdapters
4349
- * are automatically available without touching this file.
4350
- * The dotted names ('database.document', 'database.kv') are mapped explicitly.
4351
- */
4352
- getAdapter(name) {
4353
- if (name === "database.document") {
4354
- return this.platform.documentDatabase;
4355
- }
4356
- if (name === "database.kv") {
4357
- return this.platform.kvStore;
4358
- }
4359
- const adapter = this.platform[name];
4360
- if (adapter === void 0) {
4361
- throw new Error(`Unknown adapter: '${name}'`);
4362
- }
4363
- return adapter;
4364
- }
4365
4932
  isStarted() {
4366
4933
  return this.started;
4367
4934
  }
@@ -4636,19 +5203,23 @@ Caused by: ${cause.stack}`;
4636
5203
  throw new TransportError("Socket not available");
4637
5204
  }
4638
5205
  const timeout = selectTimeout(call, this.config.timeout);
5206
+ const outboundCall = this.config.authToken ? {
5207
+ ...call,
5208
+ context: { ...call.context, authToken: this.config.authToken }
5209
+ } : call;
4639
5210
  return new Promise((resolve9, reject) => {
4640
5211
  const timer = setTimeout(() => {
4641
5212
  this.pending.delete(call.requestId);
4642
5213
  reject(new TimeoutError(`Adapter call timed out after ${timeout}ms`, timeout));
4643
5214
  }, timeout);
4644
- this.pending.set(call.requestId, { resolve: resolve9, reject, timer });
4645
- const message2 = JSON.stringify(call) + "\n";
5215
+ this.pending.set(outboundCall.requestId, { resolve: resolve9, reject, timer });
5216
+ const message2 = JSON.stringify(outboundCall) + "\n";
4646
5217
  const written = this.socket.write(message2, "utf8", (error2) => {
4647
5218
  if (error2) {
4648
- const pending = this.pending.get(call.requestId);
5219
+ const pending = this.pending.get(outboundCall.requestId);
4649
5220
  if (pending) {
4650
5221
  clearTimeout(pending.timer);
4651
- this.pending.delete(call.requestId);
5222
+ this.pending.delete(outboundCall.requestId);
4652
5223
  reject(new TransportError(`Failed to write to socket: ${error2.message}`, error2));
4653
5224
  }
4654
5225
  }
@@ -4716,202 +5287,9 @@ Caused by: ${cause.stack}`;
4716
5287
  };
4717
5288
  }
4718
5289
  };
4719
- RemoteAdapter = class {
5290
+ LLMProxy = class extends RemoteAdapter {
4720
5291
  /**
4721
- * Create a remote adapter proxy.
4722
- *
4723
- * @param adapterName - Name of the adapter (e.g., 'vectorStore', 'cache')
4724
- * @param transport - Transport layer for IPC communication
4725
- * @param context - Optional execution context for tracing/debugging
4726
- */
4727
- constructor(adapterName, transport, context) {
4728
- this.adapterName = adapterName;
4729
- this.transport = transport;
4730
- this.context = context;
4731
- }
4732
- adapterName;
4733
- transport;
4734
- context;
4735
- /**
4736
- * Set execution context for this adapter.
4737
- * Context is included in all subsequent adapter calls for tracing/debugging.
4738
- *
4739
- * @param context - Execution context (traceId, pluginId, sessionId, etc.)
4740
- *
4741
- * @example
4742
- * ```typescript
4743
- * proxy.setContext({
4744
- * traceId: 'trace-abc',
4745
- * pluginId: '@kb-labs/mind',
4746
- * sessionId: 'session-xyz',
4747
- * });
4748
- * ```
4749
- */
4750
- setContext(context) {
4751
- this.context = context;
4752
- }
4753
- /**
4754
- * Get current execution context.
4755
- */
4756
- getContext() {
4757
- return this.context;
4758
- }
4759
- /**
4760
- * Call a method on the remote adapter (in parent process).
4761
- *
4762
- * This method:
4763
- * 1. Generates a unique request ID
4764
- * 2. Serializes the method arguments
4765
- * 3. Sends the call via transport
4766
- * 4. Waits for response
4767
- * 5. Deserializes and returns the result (or throws error)
4768
- *
4769
- * @param method - Method name to call on the adapter
4770
- * @param args - Method arguments (will be serialized)
4771
- * @param timeout - Optional timeout in milliseconds (overrides transport default)
4772
- * @returns Promise resolving to deserialized result
4773
- * @throws Error if remote method throws or communication fails
4774
- *
4775
- * @example
4776
- * ```typescript
4777
- * // In VectorStoreProxy.search():
4778
- * return this.callRemote('search', [query, limit, filter]);
4779
- *
4780
- * // With custom timeout for bulk operations:
4781
- * return this.callRemote('upsert', [vectors], 120000); // 2 min timeout
4782
- * ```
4783
- */
4784
- async callRemote(method, args, timeout) {
4785
- const requestId = crypto4.randomUUID();
4786
- const call = {
4787
- version: IPC_PROTOCOL_VERSION,
4788
- // Protocol version for backward compatibility
4789
- type: "adapter:call",
4790
- requestId,
4791
- adapter: this.adapterName,
4792
- method,
4793
- args: args.map((arg) => serialize(arg)),
4794
- timeout,
4795
- // Optional timeout for this specific call
4796
- context: this.context
4797
- // Include execution context for tracing/debugging
4798
- };
4799
- const response = await this.transport.send(call);
4800
- if (response.error) {
4801
- throw deserialize(response.error);
4802
- }
4803
- if (response.result === void 0) {
4804
- return void 0;
4805
- }
4806
- const result = deserialize(response.result);
4807
- if (BulkTransferHelper.isBulkTransfer(result)) {
4808
- return BulkTransferHelper.deserialize(result);
4809
- }
4810
- return result;
4811
- }
4812
- /**
4813
- * Get the adapter name this proxy represents.
4814
- */
4815
- getAdapterName() {
4816
- return this.adapterName;
4817
- }
4818
- /**
4819
- * Get the transport used by this proxy.
4820
- * Useful for advanced use cases (e.g., checking if transport is closed).
4821
- */
4822
- getTransport() {
4823
- return this.transport;
4824
- }
4825
- };
4826
- CacheProxy = class extends RemoteAdapter {
4827
- /**
4828
- * Create a cache proxy.
4829
- *
4830
- * @param transport - IPC transport to communicate with parent
4831
- */
4832
- constructor(transport) {
4833
- super("cache", transport);
4834
- }
4835
- /**
4836
- * Get a value from cache.
4837
- *
4838
- * @param key - Cache key
4839
- * @returns Cached value or null if not found/expired
4840
- */
4841
- async get(key) {
4842
- return await this.callRemote("get", [key]);
4843
- }
4844
- /**
4845
- * Set a value in cache.
4846
- *
4847
- * @param key - Cache key
4848
- * @param value - Value to cache
4849
- * @param ttl - Time to live in milliseconds (optional)
4850
- */
4851
- async set(key, value, ttl) {
4852
- await this.callRemote("set", [key, value, ttl]);
4853
- }
4854
- /**
4855
- * Delete a value from cache.
4856
- *
4857
- * @param key - Cache key
4858
- */
4859
- async delete(key) {
4860
- await this.callRemote("delete", [key]);
4861
- }
4862
- /**
4863
- * Clear cache entries matching a pattern.
4864
- *
4865
- * @param pattern - Glob pattern (e.g., 'user:*')
4866
- */
4867
- async clear(pattern) {
4868
- await this.callRemote("clear", [pattern]);
4869
- }
4870
- /**
4871
- * Add member to sorted set with score.
4872
- *
4873
- * @param key - Sorted set key
4874
- * @param score - Numeric score (typically timestamp)
4875
- * @param member - Member to add
4876
- */
4877
- async zadd(key, score, member) {
4878
- await this.callRemote("zadd", [key, score, member]);
4879
- }
4880
- /**
4881
- * Get members from sorted set by score range.
4882
- *
4883
- * @param key - Sorted set key
4884
- * @param min - Minimum score (inclusive)
4885
- * @param max - Maximum score (inclusive)
4886
- * @returns Array of members in score order
4887
- */
4888
- async zrangebyscore(key, min, max) {
4889
- return await this.callRemote("zrangebyscore", [key, min, max]);
4890
- }
4891
- /**
4892
- * Remove member from sorted set.
4893
- *
4894
- * @param key - Sorted set key
4895
- * @param member - Member to remove
4896
- */
4897
- async zrem(key, member) {
4898
- await this.callRemote("zrem", [key, member]);
4899
- }
4900
- /**
4901
- * Set key-value pair only if key does not exist (atomic operation).
4902
- *
4903
- * @param key - Cache key
4904
- * @param value - Value to set
4905
- * @param ttl - Time to live in milliseconds (optional)
4906
- * @returns true if value was set, false if key already exists
4907
- */
4908
- async setIfNotExists(key, value, ttl) {
4909
- return await this.callRemote("setIfNotExists", [key, value, ttl]);
4910
- }
4911
- };
4912
- LLMProxy = class extends RemoteAdapter {
4913
- /**
4914
- * Create an LLM proxy.
5292
+ * Create an LLM proxy.
4915
5293
  *
4916
5294
  * @param transport - IPC transport to communicate with parent
4917
5295
  */
@@ -5034,123 +5412,6 @@ Caused by: ${cause.stack}`;
5034
5412
  return this._dimensions;
5035
5413
  }
5036
5414
  };
5037
- VectorStoreProxy = class _VectorStoreProxy extends RemoteAdapter {
5038
- // Timeout for bulk operations that may trigger IPC backpressure
5039
- static BULK_OPERATION_TIMEOUT = 12e4;
5040
- // 2 minutes
5041
- // BulkTransfer configuration
5042
- bulkTransferOptions = {
5043
- maxInlineSize: 1e6,
5044
- // 1MB threshold
5045
- tempDir: process.env.KB_TEMP_DIR ?? os4.tmpdir()
5046
- };
5047
- /**
5048
- * Create a vector store proxy.
5049
- *
5050
- * @param transport - IPC transport to communicate with parent
5051
- */
5052
- constructor(transport) {
5053
- super("vectorStore", transport);
5054
- }
5055
- /**
5056
- * Search for similar vectors.
5057
- *
5058
- * @param query - Query embedding vector
5059
- * @param limit - Maximum number of results
5060
- * @param filter - Optional metadata filter
5061
- * @returns Promise resolving to search results
5062
- */
5063
- async search(query, limit, filter2, namespace) {
5064
- return await this.callRemote("search", [query, limit, filter2, namespace]);
5065
- }
5066
- /**
5067
- * Insert or update vectors.
5068
- * Uses BulkTransfer for large payloads to avoid IPC backpressure.
5069
- *
5070
- * @param vectors - Vector records to upsert
5071
- */
5072
- async upsert(vectors, namespace) {
5073
- const transfer = await BulkTransferHelper.serialize(vectors, this.bulkTransferOptions);
5074
- await this.callRemote("upsert", [transfer, namespace], _VectorStoreProxy.BULK_OPERATION_TIMEOUT);
5075
- }
5076
- /**
5077
- * Delete vectors by IDs.
5078
- * Uses extended timeout for bulk deletions.
5079
- *
5080
- * @param ids - Vector IDs to delete
5081
- */
5082
- async delete(ids, namespace) {
5083
- await this.callRemote("delete", [ids, namespace], _VectorStoreProxy.BULK_OPERATION_TIMEOUT);
5084
- }
5085
- /**
5086
- * Upsert vectors with chunk metadata (used by Mind RAG).
5087
- * Uses extended timeout for bulk operations.
5088
- *
5089
- * @param scope - Scope ID
5090
- * @param vectors - Vector records to upsert
5091
- */
5092
- async upsertChunks(scope, vectors) {
5093
- await this.callRemote("upsertChunks", [scope, vectors], _VectorStoreProxy.BULK_OPERATION_TIMEOUT);
5094
- }
5095
- /**
5096
- * Count total vectors in collection.
5097
- *
5098
- * @returns Promise resolving to vector count
5099
- */
5100
- async count(namespace) {
5101
- return await this.callRemote("count", [namespace]);
5102
- }
5103
- /**
5104
- * Get vectors by IDs.
5105
- * IDs argument is usually small, passed directly through IPC.
5106
- * Uses BulkTransfer only for large result sets.
5107
- *
5108
- * @param ids - Vector IDs to retrieve
5109
- * @returns Promise resolving to vector records
5110
- */
5111
- async get(ids, namespace) {
5112
- const resultTransfer = await this.callRemote("get", [ids, namespace], _VectorStoreProxy.BULK_OPERATION_TIMEOUT);
5113
- if (BulkTransferHelper.isBulkTransfer(resultTransfer)) {
5114
- return BulkTransferHelper.deserialize(resultTransfer);
5115
- }
5116
- return resultTransfer;
5117
- }
5118
- /**
5119
- * Query vectors by metadata filter.
5120
- * Filter argument is small, passed directly through IPC.
5121
- * Uses BulkTransfer only for potentially large result sets.
5122
- *
5123
- * @param filter - Metadata filter to apply
5124
- * @returns Promise resolving to matching vector records
5125
- */
5126
- async query(filter2, namespace) {
5127
- const resultTransfer = await this.callRemote("query", [filter2, namespace], _VectorStoreProxy.BULK_OPERATION_TIMEOUT);
5128
- if (BulkTransferHelper.isBulkTransfer(resultTransfer)) {
5129
- return BulkTransferHelper.deserialize(resultTransfer);
5130
- }
5131
- return resultTransfer;
5132
- }
5133
- /**
5134
- * Clear all vectors from collection.
5135
- * Uses extended timeout for bulk deletion.
5136
- */
5137
- async clear() {
5138
- await this.callRemote("clear", [], _VectorStoreProxy.BULK_OPERATION_TIMEOUT);
5139
- }
5140
- /**
5141
- * Initialize the vector store.
5142
- * Called during platform initialization.
5143
- */
5144
- async initialize() {
5145
- await this.callRemote("initialize", []);
5146
- }
5147
- /**
5148
- * Close connections and cleanup resources.
5149
- */
5150
- async close() {
5151
- await this.callRemote("close", []);
5152
- }
5153
- };
5154
5415
  StorageProxy = class extends RemoteAdapter {
5155
5416
  /**
5156
5417
  * Create a storage proxy.
@@ -5248,180 +5509,6 @@ Caused by: ${cause.stack}`;
5248
5509
  return await this.callRemote("listWithMetadata", [prefix]);
5249
5510
  }
5250
5511
  };
5251
- DocumentDatabaseProxy = class extends RemoteAdapter {
5252
- constructor(transport) {
5253
- super("database.document", transport);
5254
- }
5255
- async find(collection, filter2, options) {
5256
- return await this.callRemote("find", [collection, filter2, stripSignal(options)]);
5257
- }
5258
- // eslint-disable-next-line require-yield
5259
- async *findStream(_collection, _filter, _options) {
5260
- throw new Error(
5261
- "findStream() is not supported over IPC. Use bounded find({ limit }) and paginate explicitly."
5262
- );
5263
- }
5264
- async findById(collection, id, _options) {
5265
- return await this.callRemote("findById", [collection, id]);
5266
- }
5267
- async count(collection, filter2, _options) {
5268
- return await this.callRemote("count", [collection, filter2]);
5269
- }
5270
- async insertOne(collection, doc, _options) {
5271
- return await this.callRemote("insertOne", [collection, doc]);
5272
- }
5273
- async insertMany(collection, docs, _options) {
5274
- return await this.callRemote("insertMany", [collection, docs]);
5275
- }
5276
- async updateOne(collection, filter2, update, options) {
5277
- return await this.callRemote("updateOne", [
5278
- collection,
5279
- filter2,
5280
- update,
5281
- { upsert: options?.upsert }
5282
- ]);
5283
- }
5284
- async updateMany(collection, filter2, update, _options) {
5285
- return await this.callRemote("updateMany", [collection, filter2, update]);
5286
- }
5287
- async updateById(collection, id, update, _options) {
5288
- return await this.callRemote("updateById", [collection, id, update]);
5289
- }
5290
- async deleteMany(collection, filter2, _options) {
5291
- return await this.callRemote("deleteMany", [collection, filter2]);
5292
- }
5293
- async deleteById(collection, id, _options) {
5294
- return await this.callRemote("deleteById", [collection, id]);
5295
- }
5296
- async bulkWrite(collection, ops, _options) {
5297
- return await this.callRemote("bulkWrite", [collection, ops]);
5298
- }
5299
- async transaction(_fn) {
5300
- throw new Error(
5301
- "transaction() is not supported over IPC. Collect your writes into a single bulkWrite() instead."
5302
- );
5303
- }
5304
- async ensureCollection(name, options) {
5305
- await this.callRemote("ensureCollection", [name, options]);
5306
- }
5307
- async ping() {
5308
- return await this.callRemote("ping", []);
5309
- }
5310
- async close(options) {
5311
- await this.callRemote("close", [options]);
5312
- }
5313
- };
5314
- stripSignal = (options) => {
5315
- if (!options) {
5316
- return void 0;
5317
- }
5318
- const { signal: _signal, ...rest } = options;
5319
- return rest;
5320
- };
5321
- KVStoreProxy = class extends RemoteAdapter {
5322
- constructor(transport) {
5323
- super("database.kv", transport);
5324
- }
5325
- async get(key, _options) {
5326
- return await this.callRemote("get", [key]);
5327
- }
5328
- async getMany(keys, _options) {
5329
- return await this.callRemote("getMany", [keys]);
5330
- }
5331
- async set(key, value, options) {
5332
- return await this.callRemote("set", [key, value, stripSignal2(options)]);
5333
- }
5334
- async setMany(entries, _options) {
5335
- await this.callRemote("setMany", [entries]);
5336
- }
5337
- async setIfNotExists(key, value, options) {
5338
- return await this.callRemote("setIfNotExists", [key, value, stripSignal2(options)]);
5339
- }
5340
- async delete(key, _options) {
5341
- return await this.callRemote("delete", [key]);
5342
- }
5343
- async exists(key, _options) {
5344
- return await this.callRemote("exists", [key]);
5345
- }
5346
- async cas(key, expected, next, options) {
5347
- return await this.callRemote("cas", [key, expected, next, stripSignal2(options)]);
5348
- }
5349
- async incr(key, delta, options) {
5350
- return await this.callRemote("incr", [key, delta, stripSignal2(options)]);
5351
- }
5352
- async ttl(key) {
5353
- return await this.callRemote("ttl", [key]);
5354
- }
5355
- async expire(key, ttlMs) {
5356
- return await this.callRemote("expire", [key, ttlMs]);
5357
- }
5358
- async persist(key) {
5359
- return await this.callRemote("persist", [key]);
5360
- }
5361
- // eslint-disable-next-line require-yield
5362
- async *scan(_prefix, _options) {
5363
- throw new Error("scan() is not supported over IPC. Use bounded getMany() with an explicit key list.");
5364
- }
5365
- async ping() {
5366
- return await this.callRemote("ping", []);
5367
- }
5368
- async close(options) {
5369
- await this.callRemote("close", [options]);
5370
- }
5371
- };
5372
- stripSignal2 = (options) => {
5373
- if (!options) {
5374
- return void 0;
5375
- }
5376
- const { signal: _signal, ...rest } = options;
5377
- return rest;
5378
- };
5379
- ConfigProxy = class extends RemoteAdapter {
5380
- /**
5381
- * Create a config proxy.
5382
- *
5383
- * @param transport - IPC transport to communicate with parent
5384
- */
5385
- constructor(transport) {
5386
- super("config", transport);
5387
- }
5388
- /**
5389
- * Get product-specific configuration.
5390
- *
5391
- * @param productId - Product identifier (e.g., 'mind', 'workflow', 'plugins')
5392
- * @param profileId - Profile identifier (defaults to 'default' or KB_PROFILE env var)
5393
- * @returns Promise resolving to product-specific config or undefined
5394
- *
5395
- * @example
5396
- * ```typescript
5397
- * const mindConfig = await config.getConfig('mind');
5398
- * if (mindConfig?.scopes) {
5399
- * // Use scopes
5400
- * }
5401
- * ```
5402
- */
5403
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5404
- async getConfig(productId, profileId) {
5405
- return this.callRemote("getConfig", [productId, profileId]);
5406
- }
5407
- /**
5408
- * Get raw kb.config.json data.
5409
- *
5410
- * @returns Promise resolving to raw config object or undefined
5411
- *
5412
- * @example
5413
- * ```typescript
5414
- * const rawConfig = await config.getRawConfig();
5415
- * if (rawConfig) {
5416
- * const allProfiles = rawConfig.profiles;
5417
- * }
5418
- * ```
5419
- */
5420
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5421
- async getRawConfig() {
5422
- return this.callRemote("getRawConfig", []);
5423
- }
5424
- };
5425
5512
  EventBusProxy = class {
5426
5513
  constructor(transport) {
5427
5514
  this.transport = transport;
@@ -27449,21 +27536,29 @@ function getHandlerPermissions(manifest, host, id) {
27449
27536
  let handlerPerms;
27450
27537
  switch (host) {
27451
27538
  case "cli":
27452
- handlerPerms = manifest.cli?.commands.find((cmd) => cmd.path === id)?.permissions;
27539
+ handlerPerms = manifest.cli?.commands.find(
27540
+ (cmd) => cmd.path === id
27541
+ )?.permissions;
27453
27542
  break;
27454
27543
  case "rest":
27455
27544
  handlerPerms = manifest.rest?.routes.find(
27456
27545
  (route) => `${route.method} ${route.path}` === id
27457
- )?.permissions;
27546
+ )?.permissions ?? manifest.sse?.streams.find((stream2) => stream2.path === id)?.permissions;
27458
27547
  break;
27459
27548
  case "ws":
27460
- handlerPerms = manifest.ws?.channels.find((ch) => ch.path === id)?.permissions;
27549
+ handlerPerms = manifest.ws?.channels.find(
27550
+ (ch) => ch.path === id
27551
+ )?.permissions;
27461
27552
  break;
27462
27553
  case "workflow":
27463
- handlerPerms = manifest.workflows?.handlers.find((h) => h.id === id)?.permissions;
27554
+ handlerPerms = manifest.workflows?.handlers.find(
27555
+ (h) => h.id === id
27556
+ )?.permissions;
27464
27557
  break;
27465
27558
  case "webhook":
27466
- handlerPerms = manifest.webhooks?.handlers.find((h) => h.event === id)?.permissions;
27559
+ handlerPerms = manifest.webhooks?.handlers.find(
27560
+ (h) => h.event === id
27561
+ )?.permissions;
27467
27562
  break;
27468
27563
  }
27469
27564
  return {
@@ -80108,1368 +80203,330 @@ var init_container = __esm3({
80108
80203
  */
80109
80204
  initSocketServer(server) {
80110
80205
  this._socketServer = server;
80111
- }
80112
- /**
80113
- * Get socket path for IPC communication.
80114
- * Returns undefined if not running in parent process.
80115
- */
80116
- getSocketPath() {
80117
- return this._socketServer?.getSocketPath();
80118
- }
80119
- /**
80120
- * Initialize execution backend.
80121
- * Called internally by initPlatform() AFTER adapters, BEFORE core features.
80122
- *
80123
- * @param backend - ExecutionBackend instance (from @kb-labs/plugin-execution)
80124
- */
80125
- initExecutionBackend(backend) {
80126
- if (this._executionBackend) {
80127
- this.logger.warn("ExecutionBackend already initialized, replacing");
80128
- }
80129
- this._executionBackend = backend;
80130
- this.logger.debug("ExecutionBackend initialized", {
80131
- mode: backend.constructor.name
80132
- });
80133
- }
80134
- /**
80135
- * Get execution backend.
80136
- * Returns the initialized backend or throws if not initialized.
80137
- *
80138
- * @throws Error if ExecutionBackend not initialized via initPlatform()
80139
- * @returns ExecutionBackend instance
80140
- */
80141
- get executionBackend() {
80142
- if (!this._executionBackend) {
80143
- throw new Error(
80144
- "ExecutionBackend not initialized. Call initPlatform() with execution config to initialize ExecutionBackend."
80145
- );
80146
- }
80147
- return this._executionBackend;
80148
- }
80149
- /**
80150
- * Check if execution backend is initialized.
80151
- */
80152
- get hasExecutionBackend() {
80153
- return !!this._executionBackend;
80154
- }
80155
- /**
80156
- * Initialize orchestration services.
80157
- * Called internally by initPlatform() after ExecutionBackend init.
80158
- */
80159
- initOrchestrationServices(environmentManager, runExecutor, runOrchestrator) {
80160
- this._environmentManager = environmentManager;
80161
- this._runExecutor = runExecutor;
80162
- this._runOrchestrator = runOrchestrator;
80163
- }
80164
- /**
80165
- * Initialize infrastructure capability services.
80166
- * Called internally by initPlatform().
80167
- */
80168
- initCapabilityServices(workspaceManager, snapshotManager) {
80169
- this._workspaceManager = workspaceManager;
80170
- this._snapshotManager = snapshotManager;
80171
- }
80172
- /**
80173
- * Environment manager service.
80174
- * Returns undefined when not initialized (e.g., proxy/minimal platforms).
80175
- */
80176
- get environmentManager() {
80177
- return this._environmentManager;
80178
- }
80179
- /**
80180
- * Workspace manager service.
80181
- * Returns undefined when not initialized (e.g., proxy/minimal platforms).
80182
- */
80183
- get workspaceManager() {
80184
- return this._workspaceManager;
80185
- }
80186
- /**
80187
- * Snapshot manager service.
80188
- * Returns undefined when not initialized (e.g., proxy/minimal platforms).
80189
- */
80190
- get snapshotManager() {
80191
- return this._snapshotManager;
80192
- }
80193
- /**
80194
- * Run executor service.
80195
- */
80196
- get runExecutor() {
80197
- if (!this._runExecutor) {
80198
- throw new Error("RunExecutor not initialized. Call initPlatform() first.");
80199
- }
80200
- return this._runExecutor;
80201
- }
80202
- /**
80203
- * Run orchestrator service.
80204
- */
80205
- get runOrchestrator() {
80206
- if (!this._runOrchestrator) {
80207
- throw new Error(
80208
- "RunOrchestrator not initialized. Call initPlatform() first."
80209
- );
80210
- }
80211
- return this._runOrchestrator;
80212
- }
80213
- /**
80214
- * Check if platform is initialized.
80215
- */
80216
- get isInitialized() {
80217
- return this.initialized;
80218
- }
80219
- /**
80220
- * Reset platform to initial state.
80221
- * Clears all adapters and core features.
80222
- * Used primarily for testing.
80223
- */
80224
- reset() {
80225
- this.adapters.clear();
80226
- this.adapters.set("logger", new ConsoleLogger());
80227
- this.lifecycleHooks.clear();
80228
- this._workflows = void 0;
80229
- this._jobs = void 0;
80230
- this._cron = void 0;
80231
- this._resources = void 0;
80232
- this._resourceBroker = void 0;
80233
- this._socketServer = void 0;
80234
- this._executionBackend = void 0;
80235
- this._environmentManager = void 0;
80236
- this._workspaceManager = void 0;
80237
- this._snapshotManager = void 0;
80238
- this._runExecutor = void 0;
80239
- this._runOrchestrator = void 0;
80240
- this.initialized = false;
80241
- this.assembled = false;
80242
- }
80243
- /**
80244
- * Shutdown platform gracefully.
80245
- * Closes all resources, stops workers, cleanup.
80246
- */
80247
- async shutdown() {
80248
- await this.emitLifecyclePhase("beforeShutdown", {
80249
- reason: "platform.shutdown",
80250
- metadata: {
80251
- adapterCount: this.adapters.size,
80252
- hasExecutionBackend: !!this._executionBackend
80253
- }
80254
- });
80255
- if (this._executionBackend) {
80256
- try {
80257
- await this._executionBackend.shutdown();
80258
- } catch (error2) {
80259
- this.logger.warn("ExecutionBackend shutdown failed", {
80260
- error: error2 instanceof Error ? error2.message : String(error2)
80261
- });
80262
- }
80263
- }
80264
- if (this._environmentManager) {
80265
- try {
80266
- await this._environmentManager.shutdown();
80267
- } catch (error2) {
80268
- this.logger.warn("EnvironmentManager shutdown failed", {
80269
- error: error2 instanceof Error ? error2.message : String(error2)
80270
- });
80271
- }
80272
- }
80273
- if (this._workspaceManager) {
80274
- try {
80275
- await this._workspaceManager.shutdown();
80276
- } catch (error2) {
80277
- this.logger.warn("WorkspaceManager shutdown failed", {
80278
- error: error2 instanceof Error ? error2.message : String(error2)
80279
- });
80280
- }
80281
- }
80282
- if (this._snapshotManager) {
80283
- try {
80284
- await this._snapshotManager.shutdown();
80285
- } catch (error2) {
80286
- this.logger.warn("SnapshotManager shutdown failed", {
80287
- error: error2 instanceof Error ? error2.message : String(error2)
80288
- });
80289
- }
80290
- }
80291
- const adaptersInReverseLoadOrder = Array.from(this.adapters.entries()).reverse();
80292
- for (const [adapterId, adapter] of adaptersInReverseLoadOrder) {
80293
- if (!adapter || adapter === this._executionBackend) {
80294
- continue;
80295
- }
80296
- const candidate = adapter;
80297
- try {
80298
- if (typeof candidate.close === "function") {
80299
- await candidate.close.call(adapter);
80300
- } else if (typeof candidate.dispose === "function") {
80301
- await candidate.dispose.call(adapter);
80302
- } else if (typeof candidate.shutdown === "function") {
80303
- await candidate.shutdown.call(adapter);
80304
- }
80305
- } catch (error2) {
80306
- this.logger.warn("Adapter shutdown failed", {
80307
- adapterId,
80308
- error: error2 instanceof Error ? error2.message : String(error2)
80309
- });
80310
- }
80311
- }
80312
- await this.emitLifecyclePhase("shutdown", {
80313
- reason: "platform.shutdown",
80314
- metadata: {
80315
- adapterCount: this.adapters.size
80316
- }
80317
- });
80318
- }
80319
- };
80320
- PLATFORM_SINGLETON_KEY = /* @__PURE__ */ Symbol.for("kb.platform");
80321
- platform = (() => {
80322
- const existing = getPlatformFromProcess();
80323
- if (existing && typeof existing.setAdapter === "function" && typeof existing.getAdapter === "function") {
80324
- return existing;
80325
- }
80326
- const newPlatform = new PlatformContainer();
80327
- setPlatformInProcess(newPlatform);
80328
- return newPlatform;
80329
- })();
80330
- }
80331
- });
80332
- var discover_adapters_exports = {};
80333
- __export3(discover_adapters_exports, {
80334
- discoverAdapters: () => discoverAdapters,
80335
- resolveAdapter: () => resolveAdapter
80336
- });
80337
- async function loadAdapterModule(distPath) {
80338
- const fileUrl = url$1.pathToFileURL(distPath).href;
80339
- return import(fileUrl);
80340
- }
80341
- async function loadAdaptersFromLock(root, discovered, overwrite) {
80342
- const diag2 = new DiagnosticCollector();
80343
- const lock = await readMarketplaceLock(root, diag2);
80344
- if (!lock) {
80345
- return;
80346
- }
80347
- for (const [pkgId, entry] of Object.entries(lock.installed)) {
80348
- if (entry.primaryKind !== "adapter") {
80349
- continue;
80350
- }
80351
- if (entry.enabled === false) {
80352
- continue;
80353
- }
80354
- const pkgRoot = path13__namespace.default.resolve(root, entry.resolvedPath);
80355
- let mainPath = "dist/index.js";
80356
- let npmPkgName;
80357
- try {
80358
- const pkgContent = await fs5.promises.readFile(path13__namespace.default.join(pkgRoot, "package.json"), "utf-8");
80359
- const pkg = JSON.parse(pkgContent);
80360
- mainPath = pkg.main || mainPath;
80361
- npmPkgName = pkg.name;
80362
- } catch {
80363
- }
80364
- const distPath = path13__namespace.default.join(pkgRoot, mainPath);
80365
- try {
80366
- await fs5.promises.access(distPath);
80367
- const module = await loadAdapterModule(distPath);
80368
- if (typeof module.createAdapter !== "function") {
80369
- continue;
80370
- }
80371
- const adapterEntry = {
80372
- packageName: npmPkgName ?? pkgId,
80373
- pkgRoot,
80374
- createAdapter: module.createAdapter,
80375
- module
80376
- };
80377
- if (overwrite || !discovered.has(pkgId)) {
80378
- discovered.set(pkgId, adapterEntry);
80379
- }
80380
- if (npmPkgName && npmPkgName !== pkgId) {
80381
- if (overwrite || !discovered.has(npmPkgName)) {
80382
- discovered.set(npmPkgName, adapterEntry);
80383
- }
80384
- }
80385
- } catch {
80386
- }
80387
- }
80388
- }
80389
- async function discoverAdapters(platformRoot, projectRoot) {
80390
- const discovered = /* @__PURE__ */ new Map();
80391
- if (projectRoot && projectRoot !== platformRoot) {
80392
- await loadAdaptersFromLock(
80393
- projectRoot,
80394
- discovered,
80395
- /* overwrite= */
80396
- true
80397
- );
80398
- }
80399
- await loadAdaptersFromLock(
80400
- platformRoot,
80401
- discovered,
80402
- /* overwrite= */
80403
- false
80404
- );
80405
- return discovered;
80406
- }
80407
- async function resolveAdapter(adapterPath, cwd, platformRoot) {
80408
- const discovered = await discoverAdapters(
80409
- platformRoot ?? cwd,
80410
- platformRoot && platformRoot !== cwd ? cwd : void 0
80411
- );
80412
- const basePkgName = adapterPath.split("/").slice(0, 2).join("/");
80413
- const subpath = adapterPath.includes("/") ? adapterPath.split("/").slice(2).join("/") : null;
80414
- const adapter = discovered.get(basePkgName);
80415
- if (adapter && subpath) {
80416
- const subpathFile = path13__namespace.default.join(adapter.pkgRoot, "dist", `${subpath}.js`);
80417
- try {
80418
- await fs5.promises.access(subpathFile);
80419
- const module = await loadAdapterModule(subpathFile);
80420
- if (typeof module.createAdapter === "function") {
80421
- return module.createAdapter;
80422
- }
80423
- if (typeof module.default === "function") {
80424
- return module.default;
80425
- }
80426
- } catch {
80427
- }
80428
- } else if (adapter) {
80429
- return adapter.createAdapter;
80430
- }
80431
- return null;
80432
- }
80433
- var init_discover_adapters = __esm3({
80434
- "src/discover-adapters.ts"() {
80435
- }
80436
- });
80437
- var TransportError2;
80438
- var TimeoutError4;
80439
- var init_transport = __esm3({
80440
- "src/transport/transport.ts"() {
80441
- TransportError2 = class extends Error {
80442
- cause;
80443
- constructor(message2, cause) {
80444
- super(message2);
80445
- this.name = "TransportError";
80446
- this.cause = cause;
80447
- if (cause) {
80448
- this.stack = `${this.stack}
80449
- Caused by: ${cause.stack}`;
80450
- }
80451
- }
80452
- };
80453
- TimeoutError4 = class extends TransportError2 {
80454
- timeoutMs;
80455
- constructor(message2, timeoutMs) {
80456
- super(message2);
80457
- this.name = "TimeoutError";
80458
- this.timeoutMs = timeoutMs;
80459
- }
80460
- };
80461
- }
80462
- });
80463
- function getOperationTimeout2(adapter, method) {
80464
- const exactKey = `${adapter}.${method}`;
80465
- if (exactKey in OPERATION_TIMEOUTS2) {
80466
- return OPERATION_TIMEOUTS2[exactKey];
80467
- }
80468
- const wildcardKey = `${adapter}.*`;
80469
- if (wildcardKey in OPERATION_TIMEOUTS2) {
80470
- return OPERATION_TIMEOUTS2[wildcardKey];
80471
- }
80472
- return OPERATION_TIMEOUTS2["*"];
80473
- }
80474
- function selectTimeout2(call, configTimeout) {
80475
- if (call.timeout !== void 0) {
80476
- return call.timeout;
80477
- }
80478
- if (configTimeout !== void 0) {
80479
- return configTimeout;
80480
- }
80481
- return getOperationTimeout2(call.adapter, call.method);
80482
- }
80483
- var OPERATION_TIMEOUTS2;
80484
- var init_timeout_config = __esm3({
80485
- "src/transport/timeout-config.ts"() {
80486
- OPERATION_TIMEOUTS2 = {
80487
- // === VectorStore operations ===
80488
- // Bulk upsert is slow (Qdrant indexing overhead)
80489
- "vectorStore.upsert": 12e4,
80490
- // 2 minutes
80491
- // Search operations - medium latency
80492
- "vectorStore.search": 3e4,
80493
- // 30 seconds
80494
- "vectorStore.hybridSearch": 45e3,
80495
- // 45 seconds (BM25 + vector)
80496
- // Bulk retrieval - potentially large result sets
80497
- "vectorStore.get": 12e4,
80498
- // 2 minutes (retrieving many vectors)
80499
- "vectorStore.query": 12e4,
80500
- // 2 minutes (metadata filtering + retrieval)
80501
- // Collection management - fast
80502
- "vectorStore.createCollection": 15e3,
80503
- "vectorStore.deleteCollection": 15e3,
80504
- "vectorStore.collectionExists": 5e3,
80505
- // === Embeddings operations ===
80506
- // Single embed - OpenAI API latency
80507
- "embeddings.embed": 3e4,
80508
- // 30 seconds
80509
- // Batch embeddings - OpenAI processes in parallel, but may rate limit
80510
- "embeddings.embedBatch": 12e4,
80511
- // 2 minutes
80512
- // Dimension check - fast property access
80513
- "embeddings.getDimensions": 5e3,
80514
- // === LLM operations ===
80515
- // Text generation - depends on output length
80516
- "llm.generate": 9e4,
80517
- // 1.5 minutes
80518
- "llm.generateStream": 12e4,
80519
- // 2 minutes (streaming may take longer)
80520
- // === Cache operations ===
80521
- // Cache is fast (Redis or in-memory)
80522
- "cache.get": 5e3,
80523
- "cache.set": 5e3,
80524
- "cache.delete": 5e3,
80525
- "cache.clear": 1e4,
80526
- "cache.has": 5e3,
80527
- // === Storage operations ===
80528
- // File I/O - medium latency
80529
- "storage.read": 15e3,
80530
- "storage.write": 3e4,
80531
- "storage.delete": 1e4,
80532
- "storage.exists": 5e3,
80533
- "storage.list": 2e4,
80534
- // === Wildcard defaults ===
80535
- // Default timeout for any vectorStore operation not listed above
80536
- "vectorStore.*": 6e4,
80537
- // Default timeout for any embeddings operation
80538
- "embeddings.*": 6e4,
80539
- // Default timeout for any LLM operation
80540
- "llm.*": 9e4,
80541
- // Default timeout for any cache operation
80542
- "cache.*": 1e4,
80543
- // Default timeout for any storage operation
80544
- "storage.*": 3e4,
80545
- // === Global fallback ===
80546
- // Used when no specific rule matches
80547
- "*": 3e4
80548
- // 30 seconds default
80549
- };
80550
- }
80551
- });
80552
- var unix_socket_transport_exports = {};
80553
- __export3(unix_socket_transport_exports, {
80554
- UnixSocketTransport: () => UnixSocketTransport2,
80555
- createUnixSocketTransport: () => createUnixSocketTransport2
80556
- });
80557
- function createUnixSocketTransport2(config2) {
80558
- return new UnixSocketTransport2(config2);
80559
- }
80560
- var UnixSocketTransport2;
80561
- var init_unix_socket_transport = __esm3({
80562
- "src/transport/unix-socket-transport.ts"() {
80563
- init_transport();
80564
- init_timeout_config();
80565
- UnixSocketTransport2 = class {
80566
- constructor(config2 = {}) {
80567
- this.config = config2;
80568
- }
80569
- config;
80570
- socket = null;
80571
- pending = /* @__PURE__ */ new Map();
80572
- closed = false;
80573
- connecting = false;
80574
- buffer = "";
80575
- reconnectAttempts = 0;
80576
- /**
80577
- * Connect to Unix socket server.
80578
- * Called lazily on first send() or explicitly.
80579
- */
80580
- async connect() {
80581
- if (this.socket && !this.socket.destroyed) {
80582
- return;
80583
- }
80584
- if (this.connecting) {
80585
- await new Promise((resolve32) => {
80586
- setTimeout(resolve32, 100);
80587
- });
80588
- return this.connect();
80589
- }
80590
- this.connecting = true;
80591
- return new Promise((resolve32, reject) => {
80592
- const socketPath = this.config.socketPath ?? "/tmp/kb-ipc.sock";
80593
- this.socket = net__namespace.connect(socketPath);
80594
- this.socket.on("connect", () => {
80595
- this.connecting = false;
80596
- this.reconnectAttempts = 0;
80597
- resolve32();
80598
- });
80599
- this.socket.on("error", (error2) => {
80600
- this.connecting = false;
80601
- const maxAttempts = this.config.maxReconnectAttempts ?? 3;
80602
- if (this.config.autoReconnect !== false && this.reconnectAttempts < maxAttempts) {
80603
- this.reconnectAttempts++;
80604
- setTimeout(() => this.connect(), 1e3 * this.reconnectAttempts);
80605
- return;
80606
- }
80607
- reject(new TransportError2(`Unix socket connection failed: ${error2.message}`, error2));
80608
- });
80609
- this.socket.on("data", (data) => {
80610
- this.handleData(data);
80611
- });
80612
- this.socket.on("close", () => {
80613
- if (!this.closed && this.config.autoReconnect !== false) {
80614
- setTimeout(() => this.connect(), 1e3);
80615
- }
80616
- });
80617
- });
80618
- }
80619
- async send(call) {
80620
- if (this.closed) {
80621
- throw new TransportError2("Transport is closed");
80622
- }
80623
- await this.connect();
80624
- if (!this.socket || this.socket.destroyed) {
80625
- throw new TransportError2("Socket not available");
80626
- }
80627
- const timeout = selectTimeout2(call, this.config.timeout);
80628
- return new Promise((resolve32, reject) => {
80629
- const timer = setTimeout(() => {
80630
- this.pending.delete(call.requestId);
80631
- reject(new TimeoutError4(`Adapter call timed out after ${timeout}ms`, timeout));
80632
- }, timeout);
80633
- this.pending.set(call.requestId, { resolve: resolve32, reject, timer });
80634
- const message2 = JSON.stringify(call) + "\n";
80635
- const written = this.socket.write(message2, "utf8", (error2) => {
80636
- if (error2) {
80637
- const pending = this.pending.get(call.requestId);
80638
- if (pending) {
80639
- clearTimeout(pending.timer);
80640
- this.pending.delete(call.requestId);
80641
- reject(new TransportError2(`Failed to write to socket: ${error2.message}`, error2));
80642
- }
80643
- }
80644
- });
80645
- if (!written) {
80646
- this.socket.once("drain", () => {
80647
- });
80648
- }
80649
- });
80650
- }
80651
- /**
80652
- * Handle incoming data from Unix socket.
80653
- * Messages are newline-delimited JSON.
80654
- */
80655
- handleData(data) {
80656
- this.buffer += data.toString("utf8");
80657
- let newlineIndex;
80658
- while ((newlineIndex = this.buffer.indexOf("\n")) !== -1) {
80659
- const line = this.buffer.slice(0, newlineIndex);
80660
- this.buffer = this.buffer.slice(newlineIndex + 1);
80661
- if (line.trim().length === 0) {
80662
- continue;
80663
- }
80664
- try {
80665
- const msg = JSON.parse(line);
80666
- this.handleMessage(msg);
80667
- } catch {
80668
- }
80669
- }
80670
- }
80671
- handleMessage(msg) {
80672
- if (!isAdapterResponse(msg)) {
80673
- return;
80674
- }
80675
- const pending = this.pending.get(msg.requestId);
80676
- if (!pending) {
80677
- return;
80678
- }
80679
- clearTimeout(pending.timer);
80680
- this.pending.delete(msg.requestId);
80681
- pending.resolve(msg);
80682
- }
80683
- async close() {
80684
- if (this.closed) {
80685
- return;
80686
- }
80687
- this.closed = true;
80688
- if (this.socket) {
80689
- this.socket.destroy();
80690
- this.socket = null;
80691
- }
80692
- for (const [requestId, pending] of this.pending) {
80693
- clearTimeout(pending.timer);
80694
- pending.reject(new TransportError2("Transport closed"));
80695
- }
80696
- this.pending.clear();
80697
- }
80698
- isClosed() {
80699
- return this.closed;
80700
- }
80701
- };
80702
- }
80703
- });
80704
- var RemoteAdapter2;
80705
- var init_remote_adapter = __esm3({
80706
- "src/proxy/remote-adapter.ts"() {
80707
- RemoteAdapter2 = class {
80708
- /**
80709
- * Create a remote adapter proxy.
80710
- *
80711
- * @param adapterName - Name of the adapter (e.g., 'vectorStore', 'cache')
80712
- * @param transport - Transport layer for IPC communication
80713
- * @param context - Optional execution context for tracing/debugging
80714
- */
80715
- constructor(adapterName, transport, context) {
80716
- this.adapterName = adapterName;
80717
- this.transport = transport;
80718
- this.context = context;
80719
- }
80720
- adapterName;
80721
- transport;
80722
- context;
80723
- /**
80724
- * Set execution context for this adapter.
80725
- * Context is included in all subsequent adapter calls for tracing/debugging.
80726
- *
80727
- * @param context - Execution context (traceId, pluginId, sessionId, etc.)
80728
- *
80729
- * @example
80730
- * ```typescript
80731
- * proxy.setContext({
80732
- * traceId: 'trace-abc',
80733
- * pluginId: '@kb-labs/mind',
80734
- * sessionId: 'session-xyz',
80735
- * });
80736
- * ```
80737
- */
80738
- setContext(context) {
80739
- this.context = context;
80740
- }
80741
- /**
80742
- * Get current execution context.
80743
- */
80744
- getContext() {
80745
- return this.context;
80746
- }
80747
- /**
80748
- * Call a method on the remote adapter (in parent process).
80749
- *
80750
- * This method:
80751
- * 1. Generates a unique request ID
80752
- * 2. Serializes the method arguments
80753
- * 3. Sends the call via transport
80754
- * 4. Waits for response
80755
- * 5. Deserializes and returns the result (or throws error)
80756
- *
80757
- * @param method - Method name to call on the adapter
80758
- * @param args - Method arguments (will be serialized)
80759
- * @param timeout - Optional timeout in milliseconds (overrides transport default)
80760
- * @returns Promise resolving to deserialized result
80761
- * @throws Error if remote method throws or communication fails
80762
- *
80763
- * @example
80764
- * ```typescript
80765
- * // In VectorStoreProxy.search():
80766
- * return this.callRemote('search', [query, limit, filter]);
80767
- *
80768
- * // With custom timeout for bulk operations:
80769
- * return this.callRemote('upsert', [vectors], 120000); // 2 min timeout
80770
- * ```
80771
- */
80772
- async callRemote(method, args, timeout) {
80773
- const requestId = crypto4.randomUUID();
80774
- const call = {
80775
- version: IPC_PROTOCOL_VERSION,
80776
- // Protocol version for backward compatibility
80777
- type: "adapter:call",
80778
- requestId,
80779
- adapter: this.adapterName,
80780
- method,
80781
- args: args.map((arg) => serialize(arg)),
80782
- timeout,
80783
- // Optional timeout for this specific call
80784
- context: this.context
80785
- // Include execution context for tracing/debugging
80786
- };
80787
- const response = await this.transport.send(call);
80788
- if (response.error) {
80789
- throw deserialize(response.error);
80790
- }
80791
- return response.result !== void 0 ? deserialize(response.result) : void 0;
80792
- }
80793
- /**
80794
- * Get the adapter name this proxy represents.
80795
- */
80796
- getAdapterName() {
80797
- return this.adapterName;
80798
- }
80799
- /**
80800
- * Get the transport used by this proxy.
80801
- * Useful for advanced use cases (e.g., checking if transport is closed).
80802
- */
80803
- getTransport() {
80804
- return this.transport;
80805
- }
80806
- };
80807
- }
80808
- });
80809
- var BulkTransferHelper2;
80810
- var init_bulk_transfer = __esm3({
80811
- "src/transport/bulk-transfer.ts"() {
80812
- BulkTransferHelper2 = class _BulkTransferHelper2 {
80813
- /** Map of temp file IDs to file paths (for cleanup) */
80814
- static tempFiles = /* @__PURE__ */ new Map();
80815
- /** Default options */
80816
- static defaultOptions = {
80817
- maxInlineSize: 1e6,
80818
- // 1MB
80819
- tempDir: os4.tmpdir()
80820
- };
80821
- /**
80822
- * Serialize data: inline for small, temp file for large
80823
- *
80824
- * @example
80825
- * ```typescript
80826
- * const transfer = await BulkTransferHelper.serialize(vectors, {
80827
- * maxInlineSize: 1_000_000,
80828
- * tempDir: '/tmp'
80829
- * });
80830
- *
80831
- * if (transfer.type === 'inline') {
80832
- * console.log('Using inline IPC');
80833
- * } else {
80834
- * console.log('Using temp file:', transfer.payload); // Absolute path like '/tmp/bulk-123.json'
80835
- * }
80836
- * ```
80837
- */
80838
- static async serialize(data, options = {}) {
80839
- const opts = { ...this.defaultOptions, ...options };
80840
- const json3 = JSON.stringify(data);
80841
- if (json3.length < opts.maxInlineSize) {
80842
- return { type: "inline", payload: json3 };
80843
- }
80844
- const tempId = `bulk-${Date.now()}-${Math.random().toString(36).slice(2)}`;
80845
- const tempPath = path13.join(opts.tempDir, `${tempId}.json`);
80846
- await fs2.writeFile(tempPath, json3, "utf8");
80847
- this.tempFiles.set(tempPath, tempPath);
80848
- return { type: "file", payload: tempPath };
80849
- }
80850
- /**
80851
- * Deserialize from inline JSON or temp file
80852
- *
80853
- * @example
80854
- * ```typescript
80855
- * const transfer = { type: 'file', payload: '/tmp/bulk-123.json' };
80856
- * const data = await BulkTransferHelper.deserialize<VectorRecord[]>(transfer);
80857
- * ```
80858
- */
80859
- static async deserialize(transfer) {
80860
- if (transfer.type === "inline") {
80861
- return JSON.parse(transfer.payload);
80862
- }
80863
- const tempPath = transfer.payload;
80864
- try {
80865
- const json3 = await fs2.readFile(tempPath, "utf8");
80866
- return JSON.parse(json3);
80867
- } finally {
80868
- await fs2.unlink(tempPath).catch(() => {
80869
- });
80870
- this.tempFiles.delete(tempPath);
80871
- }
80872
- }
80873
- /**
80874
- * Check if object is a BulkTransfer
80875
- */
80876
- static isBulkTransfer(obj) {
80877
- return typeof obj === "object" && obj !== null && "type" in obj && "payload" in obj && (obj.type === "inline" || obj.type === "file");
80878
- }
80879
- /**
80880
- * Cleanup all temp files (call on process exit)
80881
- */
80882
- static async cleanup() {
80883
- const cleanupPromises = Array.from(this.tempFiles.values()).map(
80884
- (path62) => fs2.unlink(path62).catch(() => {
80885
- })
80886
- );
80887
- await Promise.all(cleanupPromises);
80888
- this.tempFiles.clear();
80889
- }
80890
- /**
80891
- * Get statistics about temp files
80892
- */
80893
- static getStats() {
80894
- return {
80895
- tempFilesCount: this.tempFiles.size,
80896
- tempFilePaths: Array.from(this.tempFiles.values())
80897
- };
80898
- }
80899
- static registerSignalHandlers() {
80900
- process.on("SIGINT", async () => {
80901
- await _BulkTransferHelper2.cleanup();
80902
- process.exit(0);
80903
- });
80904
- process.on("SIGTERM", async () => {
80905
- await _BulkTransferHelper2.cleanup();
80906
- process.exit(0);
80907
- });
80908
- process.on("uncaughtException", async (error2) => {
80909
- console.error("[BulkTransferHelper] Uncaught exception, cleaning up temp files:", error2);
80910
- await _BulkTransferHelper2.cleanup();
80911
- process.exit(1);
80912
- });
80913
- }
80914
- };
80915
- process.on("exit", () => {
80916
- for (const path62 of BulkTransferHelper2.getStats().tempFilePaths) {
80917
- try {
80918
- fs5.unlinkSync(path62);
80919
- } catch {
80920
- }
80921
- }
80922
- });
80923
- }
80924
- });
80925
- var vector_store_proxy_exports = {};
80926
- __export3(vector_store_proxy_exports, {
80927
- VectorStoreProxy: () => VectorStoreProxy2,
80928
- createVectorStoreProxy: () => createVectorStoreProxy
80929
- });
80930
- function createVectorStoreProxy(transport) {
80931
- return new VectorStoreProxy2(transport);
80932
- }
80933
- var VectorStoreProxy2;
80934
- var init_vector_store_proxy = __esm3({
80935
- "src/proxy/vector-store-proxy.ts"() {
80936
- init_remote_adapter();
80937
- init_bulk_transfer();
80938
- VectorStoreProxy2 = class _VectorStoreProxy2 extends RemoteAdapter2 {
80939
- // Timeout for bulk operations that may trigger IPC backpressure
80940
- static BULK_OPERATION_TIMEOUT = 12e4;
80941
- // 2 minutes
80942
- // BulkTransfer configuration
80943
- bulkTransferOptions = {
80944
- maxInlineSize: 1e6,
80945
- // 1MB threshold
80946
- tempDir: process.env.KB_TEMP_DIR ?? os4.tmpdir()
80947
- };
80948
- /**
80949
- * Create a vector store proxy.
80950
- *
80951
- * @param transport - IPC transport to communicate with parent
80952
- */
80953
- constructor(transport) {
80954
- super("vectorStore", transport);
80955
- }
80956
- /**
80957
- * Search for similar vectors.
80958
- *
80959
- * @param query - Query embedding vector
80960
- * @param limit - Maximum number of results
80961
- * @param filter - Optional metadata filter
80962
- * @returns Promise resolving to search results
80963
- */
80964
- async search(query, limit, filter2, namespace) {
80965
- return await this.callRemote("search", [query, limit, filter2, namespace]);
80966
- }
80967
- /**
80968
- * Insert or update vectors.
80969
- * Uses BulkTransfer for large payloads to avoid IPC backpressure.
80970
- *
80971
- * @param vectors - Vector records to upsert
80972
- */
80973
- async upsert(vectors, namespace) {
80974
- const transfer = await BulkTransferHelper2.serialize(vectors, this.bulkTransferOptions);
80975
- await this.callRemote("upsert", [transfer, namespace], _VectorStoreProxy2.BULK_OPERATION_TIMEOUT);
80976
- }
80977
- /**
80978
- * Delete vectors by IDs.
80979
- * Uses extended timeout for bulk deletions.
80980
- *
80981
- * @param ids - Vector IDs to delete
80982
- */
80983
- async delete(ids, namespace) {
80984
- await this.callRemote("delete", [ids, namespace], _VectorStoreProxy2.BULK_OPERATION_TIMEOUT);
80985
- }
80986
- /**
80987
- * Upsert vectors with chunk metadata (used by Mind RAG).
80988
- * Uses extended timeout for bulk operations.
80989
- *
80990
- * @param scope - Scope ID
80991
- * @param vectors - Vector records to upsert
80992
- */
80993
- async upsertChunks(scope, vectors) {
80994
- await this.callRemote("upsertChunks", [scope, vectors], _VectorStoreProxy2.BULK_OPERATION_TIMEOUT);
80995
- }
80996
- /**
80997
- * Count total vectors in collection.
80998
- *
80999
- * @returns Promise resolving to vector count
81000
- */
81001
- async count(namespace) {
81002
- return await this.callRemote("count", [namespace]);
81003
- }
81004
- /**
81005
- * Get vectors by IDs.
81006
- * IDs argument is usually small, passed directly through IPC.
81007
- * Uses BulkTransfer only for large result sets.
81008
- *
81009
- * @param ids - Vector IDs to retrieve
81010
- * @returns Promise resolving to vector records
81011
- */
81012
- async get(ids, namespace) {
81013
- const resultTransfer = await this.callRemote("get", [ids, namespace], _VectorStoreProxy2.BULK_OPERATION_TIMEOUT);
81014
- if (BulkTransferHelper2.isBulkTransfer(resultTransfer)) {
81015
- return BulkTransferHelper2.deserialize(resultTransfer);
81016
- }
81017
- return resultTransfer;
81018
- }
81019
- /**
81020
- * Query vectors by metadata filter.
81021
- * Filter argument is small, passed directly through IPC.
81022
- * Uses BulkTransfer only for potentially large result sets.
81023
- *
81024
- * @param filter - Metadata filter to apply
81025
- * @returns Promise resolving to matching vector records
81026
- */
81027
- async query(filter2, namespace) {
81028
- const resultTransfer = await this.callRemote("query", [filter2, namespace], _VectorStoreProxy2.BULK_OPERATION_TIMEOUT);
81029
- if (BulkTransferHelper2.isBulkTransfer(resultTransfer)) {
81030
- return BulkTransferHelper2.deserialize(resultTransfer);
81031
- }
81032
- return resultTransfer;
81033
- }
81034
- /**
81035
- * Clear all vectors from collection.
81036
- * Uses extended timeout for bulk deletion.
81037
- */
81038
- async clear() {
81039
- await this.callRemote("clear", [], _VectorStoreProxy2.BULK_OPERATION_TIMEOUT);
81040
- }
81041
- /**
81042
- * Initialize the vector store.
81043
- * Called during platform initialization.
81044
- */
81045
- async initialize() {
81046
- await this.callRemote("initialize", []);
81047
- }
81048
- /**
81049
- * Close connections and cleanup resources.
81050
- */
81051
- async close() {
81052
- await this.callRemote("close", []);
81053
- }
81054
- };
81055
- }
81056
- });
81057
- var cache_proxy_exports = {};
81058
- __export3(cache_proxy_exports, {
81059
- CacheProxy: () => CacheProxy2,
81060
- createCacheProxy: () => createCacheProxy
81061
- });
81062
- function createCacheProxy(transport) {
81063
- return new CacheProxy2(transport);
81064
- }
81065
- var CacheProxy2;
81066
- var init_cache_proxy = __esm3({
81067
- "src/proxy/cache-proxy.ts"() {
81068
- init_remote_adapter();
81069
- CacheProxy2 = class extends RemoteAdapter2 {
81070
- /**
81071
- * Create a cache proxy.
81072
- *
81073
- * @param transport - IPC transport to communicate with parent
81074
- */
81075
- constructor(transport) {
81076
- super("cache", transport);
81077
- }
81078
- /**
81079
- * Get a value from cache.
81080
- *
81081
- * @param key - Cache key
81082
- * @returns Cached value or null if not found/expired
81083
- */
81084
- async get(key) {
81085
- return await this.callRemote("get", [key]);
81086
- }
81087
- /**
81088
- * Set a value in cache.
81089
- *
81090
- * @param key - Cache key
81091
- * @param value - Value to cache
81092
- * @param ttl - Time to live in milliseconds (optional)
81093
- */
81094
- async set(key, value, ttl) {
81095
- await this.callRemote("set", [key, value, ttl]);
81096
- }
81097
- /**
81098
- * Delete a value from cache.
81099
- *
81100
- * @param key - Cache key
81101
- */
81102
- async delete(key) {
81103
- await this.callRemote("delete", [key]);
81104
- }
81105
- /**
81106
- * Clear cache entries matching a pattern.
81107
- *
81108
- * @param pattern - Glob pattern (e.g., 'user:*')
81109
- */
81110
- async clear(pattern) {
81111
- await this.callRemote("clear", [pattern]);
81112
- }
81113
- /**
81114
- * Add member to sorted set with score.
81115
- *
81116
- * @param key - Sorted set key
81117
- * @param score - Numeric score (typically timestamp)
81118
- * @param member - Member to add
81119
- */
81120
- async zadd(key, score, member) {
81121
- await this.callRemote("zadd", [key, score, member]);
81122
- }
81123
- /**
81124
- * Get members from sorted set by score range.
81125
- *
81126
- * @param key - Sorted set key
81127
- * @param min - Minimum score (inclusive)
81128
- * @param max - Maximum score (inclusive)
81129
- * @returns Array of members in score order
81130
- */
81131
- async zrangebyscore(key, min, max) {
81132
- return await this.callRemote("zrangebyscore", [key, min, max]);
81133
- }
81134
- /**
81135
- * Remove member from sorted set.
81136
- *
81137
- * @param key - Sorted set key
81138
- * @param member - Member to remove
81139
- */
81140
- async zrem(key, member) {
81141
- await this.callRemote("zrem", [key, member]);
81142
- }
81143
- /**
81144
- * Set key-value pair only if key does not exist (atomic operation).
81145
- *
81146
- * @param key - Cache key
81147
- * @param value - Value to set
81148
- * @param ttl - Time to live in milliseconds (optional)
81149
- * @returns true if value was set, false if key already exists
81150
- */
81151
- async setIfNotExists(key, value, ttl) {
81152
- return await this.callRemote("setIfNotExists", [key, value, ttl]);
81153
- }
81154
- };
81155
- }
81156
- });
81157
- var config_proxy_exports = {};
81158
- __export3(config_proxy_exports, {
81159
- ConfigProxy: () => ConfigProxy2
81160
- });
81161
- var ConfigProxy2;
81162
- var init_config_proxy = __esm3({
81163
- "src/proxy/config-proxy.ts"() {
81164
- init_remote_adapter();
81165
- ConfigProxy2 = class extends RemoteAdapter2 {
81166
- /**
81167
- * Create a config proxy.
81168
- *
81169
- * @param transport - IPC transport to communicate with parent
81170
- */
81171
- constructor(transport) {
81172
- super("config", transport);
81173
- }
81174
- /**
81175
- * Get product-specific configuration.
81176
- *
81177
- * @param productId - Product identifier (e.g., 'mind', 'workflow', 'plugins')
81178
- * @param profileId - Profile identifier (defaults to 'default' or KB_PROFILE env var)
81179
- * @returns Promise resolving to product-specific config or undefined
81180
- *
81181
- * @example
81182
- * ```typescript
81183
- * const mindConfig = await config.getConfig('mind');
81184
- * if (mindConfig?.scopes) {
81185
- * // Use scopes
81186
- * }
81187
- * ```
81188
- */
81189
- async getConfig(productId, profileId) {
81190
- return this.callRemote("getConfig", [productId, profileId]);
81191
- }
81192
- /**
81193
- * Get raw kb.config.json data.
81194
- *
81195
- * @returns Promise resolving to raw config object or undefined
81196
- *
81197
- * @example
81198
- * ```typescript
81199
- * const rawConfig = await config.getRawConfig();
81200
- * if (rawConfig) {
81201
- * const allProfiles = rawConfig.profiles;
81202
- * }
81203
- * ```
81204
- */
81205
- async getRawConfig() {
81206
- return this.callRemote("getRawConfig", []);
81207
- }
81208
- };
81209
- }
81210
- });
81211
- var llm_proxy_exports = {};
81212
- __export3(llm_proxy_exports, {
81213
- LLMProxy: () => LLMProxy2,
81214
- createLLMProxy: () => createLLMProxy
81215
- });
81216
- function createLLMProxy(transport) {
81217
- return new LLMProxy2(transport);
81218
- }
81219
- var LLMProxy2;
81220
- var init_llm_proxy = __esm3({
81221
- "src/proxy/llm-proxy.ts"() {
81222
- init_remote_adapter();
81223
- LLMProxy2 = class extends RemoteAdapter2 {
81224
- /**
81225
- * Create an LLM proxy.
81226
- *
81227
- * @param transport - IPC transport to communicate with parent
81228
- */
81229
- constructor(transport) {
81230
- super("llm", transport);
81231
- }
81232
- /**
81233
- * Generate a completion for the given prompt.
81234
- *
81235
- * @param prompt - Text prompt
81236
- * @param options - Optional generation options
81237
- * @returns LLM response with content and token usage
81238
- */
81239
- async complete(prompt, options) {
81240
- return await this.callRemote("complete", [prompt, options]);
81241
- }
81242
- getProtocolCapabilities() {
81243
- return {
81244
- cache: { supported: false },
81245
- stream: { supported: false }
81246
- };
81247
- }
81248
- /**
81249
- * Stream a completion for the given prompt.
81250
- *
81251
- * **Fallback over IPC**: Uses complete() and emits a single chunk.
81252
- *
81253
- * Streaming requires bidirectional communication which is not
81254
- * currently implemented in the IPC protocol. This fallback preserves
81255
- * API compatibility for callers expecting AsyncIterable<string>.
81256
- *
81257
- * @param prompt - Text prompt
81258
- * @param options - Optional generation options
81259
- * @returns Async iterable with a single chunk from complete()
81260
- */
81261
- async *stream(prompt, options) {
81262
- console.warn("[LLMProxy] stream() fallback via complete() over IPC.");
81263
- const response = await this.complete(prompt, options);
81264
- if (response.content) {
81265
- yield response.content;
81266
- }
81267
- }
81268
- /**
81269
- * Chat with native tool calling support.
81270
- *
81271
- * Forwards tool calling request to parent process via IPC.
81272
- *
81273
- * @param messages - Conversation history
81274
- * @param options - Options including tools and tool choice
81275
- * @returns LLM response with optional tool calls
81276
- */
81277
- async chatWithTools(messages, options) {
81278
- return await this.callRemote("chatWithTools", [messages, options]);
81279
- }
81280
- };
81281
- }
81282
- });
81283
- var embeddings_proxy_exports = {};
81284
- __export3(embeddings_proxy_exports, {
81285
- EmbeddingsProxy: () => EmbeddingsProxy2,
81286
- createEmbeddingsProxy: () => createEmbeddingsProxy
81287
- });
81288
- function createEmbeddingsProxy(transport, dimensions) {
81289
- return new EmbeddingsProxy2(transport, dimensions);
81290
- }
81291
- var EmbeddingsProxy2;
81292
- var init_embeddings_proxy = __esm3({
81293
- "src/proxy/embeddings-proxy.ts"() {
81294
- init_remote_adapter();
81295
- EmbeddingsProxy2 = class extends RemoteAdapter2 {
81296
- _dimensions;
81297
- /**
81298
- * Create an embeddings proxy.
81299
- *
81300
- * @param transport - IPC transport to communicate with parent
81301
- * @param dimensions - Optional dimensions override (avoids IPC call)
81302
- */
81303
- constructor(transport, dimensions) {
81304
- super("embeddings", transport);
81305
- this._dimensions = dimensions;
81306
- }
81307
- /**
81308
- * Generate embedding vector for a single text.
81309
- *
81310
- * @param text - Input text
81311
- * @returns Embedding vector
80206
+ }
80207
+ /**
80208
+ * Get socket path for IPC communication.
80209
+ * Returns undefined if not running in parent process.
81312
80210
  */
81313
- async embed(text) {
81314
- return await this.callRemote("embed", [text]);
80211
+ getSocketPath() {
80212
+ return this._socketServer?.getSocketPath();
81315
80213
  }
81316
80214
  /**
81317
- * Generate embedding vectors for multiple texts.
80215
+ * Initialize execution backend.
80216
+ * Called internally by initPlatform() AFTER adapters, BEFORE core features.
81318
80217
  *
81319
- * @param texts - Array of input texts
81320
- * @returns Array of embedding vectors (same order as input)
80218
+ * @param backend - ExecutionBackend instance (from @kb-labs/plugin-execution)
81321
80219
  */
81322
- async embedBatch(texts) {
81323
- return await this.callRemote("embedBatch", [texts]);
80220
+ initExecutionBackend(backend) {
80221
+ if (this._executionBackend) {
80222
+ this.logger.warn("ExecutionBackend already initialized, replacing");
80223
+ }
80224
+ this._executionBackend = backend;
80225
+ this.logger.debug("ExecutionBackend initialized", {
80226
+ mode: backend.constructor.name
80227
+ });
81324
80228
  }
81325
80229
  /**
81326
- * Dimension of the embedding vectors.
80230
+ * Get execution backend.
80231
+ * Returns the initialized backend or throws if not initialized.
81327
80232
  *
81328
- * This value is fetched once from the parent on first access
81329
- * and cached locally for performance.
80233
+ * @throws Error if ExecutionBackend not initialized via initPlatform()
80234
+ * @returns ExecutionBackend instance
81330
80235
  */
81331
- get dimensions() {
81332
- if (this._dimensions === void 0) {
80236
+ get executionBackend() {
80237
+ if (!this._executionBackend) {
81333
80238
  throw new Error(
81334
- "EmbeddingsProxy dimensions not initialized. Call getDimensions() first or pass dimensions to constructor."
80239
+ "ExecutionBackend not initialized. Call initPlatform() with execution config to initialize ExecutionBackend."
81335
80240
  );
81336
80241
  }
81337
- return this._dimensions;
80242
+ return this._executionBackend;
81338
80243
  }
81339
80244
  /**
81340
- * Initialize dimensions by fetching from parent.
81341
- *
81342
- * This is called automatically by initPlatform() in child process.
81343
- * If you create EmbeddingsProxy manually, call this method before
81344
- * accessing the `dimensions` property.
81345
- *
81346
- * @returns Dimensions value
81347
- *
81348
- * @example
81349
- * ```typescript
81350
- * const proxy = new EmbeddingsProxy(transport);
81351
- * await proxy.getDimensions(); // Fetch once
81352
- * console.log(proxy.dimensions); // Now safe to access
81353
- * ```
80245
+ * Check if execution backend is initialized.
81354
80246
  */
81355
- async getDimensions() {
81356
- if (this._dimensions === void 0) {
81357
- this._dimensions = await this.callRemote("getDimensions", []);
81358
- }
81359
- return this._dimensions;
80247
+ get hasExecutionBackend() {
80248
+ return !!this._executionBackend;
81360
80249
  }
81361
- };
81362
- }
81363
- });
81364
- var storage_proxy_exports = {};
81365
- __export3(storage_proxy_exports, {
81366
- StorageProxy: () => StorageProxy2,
81367
- createStorageProxy: () => createStorageProxy
81368
- });
81369
- function createStorageProxy(transport) {
81370
- return new StorageProxy2(transport);
81371
- }
81372
- var StorageProxy2;
81373
- var init_storage_proxy = __esm3({
81374
- "src/proxy/storage-proxy.ts"() {
81375
- init_remote_adapter();
81376
- StorageProxy2 = class extends RemoteAdapter2 {
81377
80250
  /**
81378
- * Create a storage proxy.
81379
- *
81380
- * @param transport - IPC transport to communicate with parent
80251
+ * Initialize orchestration services.
80252
+ * Called internally by initPlatform() after ExecutionBackend init.
81381
80253
  */
81382
- constructor(transport) {
81383
- super("storage", transport);
80254
+ initOrchestrationServices(environmentManager, runExecutor, runOrchestrator) {
80255
+ this._environmentManager = environmentManager;
80256
+ this._runExecutor = runExecutor;
80257
+ this._runOrchestrator = runOrchestrator;
81384
80258
  }
81385
80259
  /**
81386
- * Read file contents.
81387
- *
81388
- * @param path - File path
81389
- * @returns File contents or null if not found
80260
+ * Initialize infrastructure capability services.
80261
+ * Called internally by initPlatform().
81390
80262
  */
81391
- async read(path62) {
81392
- return await this.callRemote("read", [path62]);
80263
+ initCapabilityServices(workspaceManager, snapshotManager) {
80264
+ this._workspaceManager = workspaceManager;
80265
+ this._snapshotManager = snapshotManager;
81393
80266
  }
81394
80267
  /**
81395
- * Write file contents.
81396
- *
81397
- * @param path - File path
81398
- * @param data - File contents
80268
+ * Environment manager service.
80269
+ * Returns undefined when not initialized (e.g., proxy/minimal platforms).
81399
80270
  */
81400
- async write(path62, data) {
81401
- await this.callRemote("write", [path62, data]);
80271
+ get environmentManager() {
80272
+ return this._environmentManager;
81402
80273
  }
81403
80274
  /**
81404
- * Delete a file.
81405
- *
81406
- * @param path - File path
80275
+ * Workspace manager service.
80276
+ * Returns undefined when not initialized (e.g., proxy/minimal platforms).
81407
80277
  */
81408
- async delete(path62) {
81409
- await this.callRemote("delete", [path62]);
80278
+ get workspaceManager() {
80279
+ return this._workspaceManager;
81410
80280
  }
81411
80281
  /**
81412
- * List files matching a prefix.
81413
- *
81414
- * @param prefix - Path prefix (e.g., 'docs/')
81415
- * @returns Array of file paths
80282
+ * Snapshot manager service.
80283
+ * Returns undefined when not initialized (e.g., proxy/minimal platforms).
81416
80284
  */
81417
- async list(prefix) {
81418
- return await this.callRemote("list", [prefix]);
80285
+ get snapshotManager() {
80286
+ return this._snapshotManager;
81419
80287
  }
81420
80288
  /**
81421
- * Check if a file exists.
81422
- *
81423
- * @param path - File path
81424
- * @returns True if file exists, false otherwise
80289
+ * Run executor service.
81425
80290
  */
81426
- async exists(path62) {
81427
- return await this.callRemote("exists", [path62]);
80291
+ get runExecutor() {
80292
+ if (!this._runExecutor) {
80293
+ throw new Error("RunExecutor not initialized. Call initPlatform() first.");
80294
+ }
80295
+ return this._runExecutor;
81428
80296
  }
81429
- // ═══════════════════════════════════════════════════════════════════════
81430
- // EXTENDED METHODS (optional - implements IStorage extended interface)
81431
- // ═══════════════════════════════════════════════════════════════════════
81432
80297
  /**
81433
- * Get file metadata.
81434
- * Optional method - implements IStorage.stat().
81435
- *
81436
- * @param path - File path
81437
- * @returns File metadata or null if not found
80298
+ * Run orchestrator service.
81438
80299
  */
81439
- async stat(path62) {
81440
- return await this.callRemote("stat", [path62]);
80300
+ get runOrchestrator() {
80301
+ if (!this._runOrchestrator) {
80302
+ throw new Error(
80303
+ "RunOrchestrator not initialized. Call initPlatform() first."
80304
+ );
80305
+ }
80306
+ return this._runOrchestrator;
81441
80307
  }
81442
80308
  /**
81443
- * Copy file within storage.
81444
- * Optional method - implements IStorage.copy().
81445
- *
81446
- * @param sourcePath - Source file path
81447
- * @param destPath - Destination file path
80309
+ * Check if platform is initialized.
81448
80310
  */
81449
- async copy(sourcePath, destPath) {
81450
- await this.callRemote("copy", [sourcePath, destPath]);
80311
+ get isInitialized() {
80312
+ return this.initialized;
81451
80313
  }
81452
80314
  /**
81453
- * Move file within storage.
81454
- * Optional method - implements IStorage.move().
81455
- *
81456
- * @param sourcePath - Source file path
81457
- * @param destPath - Destination file path
80315
+ * Reset platform to initial state.
80316
+ * Clears all adapters and core features.
80317
+ * Used primarily for testing.
81458
80318
  */
81459
- async move(sourcePath, destPath) {
81460
- await this.callRemote("move", [sourcePath, destPath]);
80319
+ reset() {
80320
+ this.adapters.clear();
80321
+ this.adapters.set("logger", new ConsoleLogger());
80322
+ this.lifecycleHooks.clear();
80323
+ this._workflows = void 0;
80324
+ this._jobs = void 0;
80325
+ this._cron = void 0;
80326
+ this._resources = void 0;
80327
+ this._resourceBroker = void 0;
80328
+ this._socketServer = void 0;
80329
+ this._executionBackend = void 0;
80330
+ this._environmentManager = void 0;
80331
+ this._workspaceManager = void 0;
80332
+ this._snapshotManager = void 0;
80333
+ this._runExecutor = void 0;
80334
+ this._runOrchestrator = void 0;
80335
+ this.initialized = false;
80336
+ this.assembled = false;
81461
80337
  }
81462
80338
  /**
81463
- * List files with metadata.
81464
- * Optional method - implements IStorage.listWithMetadata().
81465
- *
81466
- * @param prefix - Path prefix (e.g., 'docs/')
81467
- * @returns Array of file metadata
80339
+ * Shutdown platform gracefully.
80340
+ * Closes all resources, stops workers, cleanup.
81468
80341
  */
81469
- async listWithMetadata(prefix) {
81470
- return await this.callRemote("listWithMetadata", [prefix]);
80342
+ async shutdown() {
80343
+ await this.emitLifecyclePhase("beforeShutdown", {
80344
+ reason: "platform.shutdown",
80345
+ metadata: {
80346
+ adapterCount: this.adapters.size,
80347
+ hasExecutionBackend: !!this._executionBackend
80348
+ }
80349
+ });
80350
+ if (this._executionBackend) {
80351
+ try {
80352
+ await this._executionBackend.shutdown();
80353
+ } catch (error2) {
80354
+ this.logger.warn("ExecutionBackend shutdown failed", {
80355
+ error: error2 instanceof Error ? error2.message : String(error2)
80356
+ });
80357
+ }
80358
+ }
80359
+ if (this._environmentManager) {
80360
+ try {
80361
+ await this._environmentManager.shutdown();
80362
+ } catch (error2) {
80363
+ this.logger.warn("EnvironmentManager shutdown failed", {
80364
+ error: error2 instanceof Error ? error2.message : String(error2)
80365
+ });
80366
+ }
80367
+ }
80368
+ if (this._workspaceManager) {
80369
+ try {
80370
+ await this._workspaceManager.shutdown();
80371
+ } catch (error2) {
80372
+ this.logger.warn("WorkspaceManager shutdown failed", {
80373
+ error: error2 instanceof Error ? error2.message : String(error2)
80374
+ });
80375
+ }
80376
+ }
80377
+ if (this._snapshotManager) {
80378
+ try {
80379
+ await this._snapshotManager.shutdown();
80380
+ } catch (error2) {
80381
+ this.logger.warn("SnapshotManager shutdown failed", {
80382
+ error: error2 instanceof Error ? error2.message : String(error2)
80383
+ });
80384
+ }
80385
+ }
80386
+ const adaptersInReverseLoadOrder = Array.from(this.adapters.entries()).reverse();
80387
+ for (const [adapterId, adapter] of adaptersInReverseLoadOrder) {
80388
+ if (!adapter || adapter === this._executionBackend) {
80389
+ continue;
80390
+ }
80391
+ const candidate = adapter;
80392
+ try {
80393
+ if (typeof candidate.close === "function") {
80394
+ await candidate.close.call(adapter);
80395
+ } else if (typeof candidate.dispose === "function") {
80396
+ await candidate.dispose.call(adapter);
80397
+ } else if (typeof candidate.shutdown === "function") {
80398
+ await candidate.shutdown.call(adapter);
80399
+ }
80400
+ } catch (error2) {
80401
+ this.logger.warn("Adapter shutdown failed", {
80402
+ adapterId,
80403
+ error: error2 instanceof Error ? error2.message : String(error2)
80404
+ });
80405
+ }
80406
+ }
80407
+ await this.emitLifecyclePhase("shutdown", {
80408
+ reason: "platform.shutdown",
80409
+ metadata: {
80410
+ adapterCount: this.adapters.size
80411
+ }
80412
+ });
81471
80413
  }
81472
80414
  };
80415
+ PLATFORM_SINGLETON_KEY = /* @__PURE__ */ Symbol.for("kb.platform");
80416
+ platform = (() => {
80417
+ const existing = getPlatformFromProcess();
80418
+ if (existing && typeof existing.setAdapter === "function" && typeof existing.getAdapter === "function") {
80419
+ return existing;
80420
+ }
80421
+ const newPlatform = new PlatformContainer();
80422
+ setPlatformInProcess(newPlatform);
80423
+ return newPlatform;
80424
+ })();
80425
+ }
80426
+ });
80427
+ var discover_adapters_exports = {};
80428
+ __export3(discover_adapters_exports, {
80429
+ discoverAdapters: () => discoverAdapters,
80430
+ resolveAdapter: () => resolveAdapter
80431
+ });
80432
+ async function loadAdapterModule(distPath) {
80433
+ const fileUrl = url$1.pathToFileURL(distPath).href;
80434
+ return import(fileUrl);
80435
+ }
80436
+ async function loadAdaptersFromLock(root, discovered, overwrite) {
80437
+ const diag2 = new DiagnosticCollector();
80438
+ const lock = await readMarketplaceLock(root, diag2);
80439
+ if (!lock) {
80440
+ return;
80441
+ }
80442
+ for (const [pkgId, entry] of Object.entries(lock.installed)) {
80443
+ if (entry.primaryKind !== "adapter") {
80444
+ continue;
80445
+ }
80446
+ if (entry.enabled === false) {
80447
+ continue;
80448
+ }
80449
+ const pkgRoot = path13__namespace.default.resolve(root, entry.resolvedPath);
80450
+ let mainPath = "dist/index.js";
80451
+ let npmPkgName;
80452
+ try {
80453
+ const pkgContent = await fs5.promises.readFile(path13__namespace.default.join(pkgRoot, "package.json"), "utf-8");
80454
+ const pkg = JSON.parse(pkgContent);
80455
+ mainPath = pkg.main || mainPath;
80456
+ npmPkgName = pkg.name;
80457
+ } catch {
80458
+ }
80459
+ const distPath = path13__namespace.default.join(pkgRoot, mainPath);
80460
+ try {
80461
+ await fs5.promises.access(distPath);
80462
+ const module = await loadAdapterModule(distPath);
80463
+ if (typeof module.createAdapter !== "function") {
80464
+ continue;
80465
+ }
80466
+ const adapterEntry = {
80467
+ packageName: npmPkgName ?? pkgId,
80468
+ pkgRoot,
80469
+ createAdapter: module.createAdapter,
80470
+ module
80471
+ };
80472
+ if (overwrite || !discovered.has(pkgId)) {
80473
+ discovered.set(pkgId, adapterEntry);
80474
+ }
80475
+ if (npmPkgName && npmPkgName !== pkgId) {
80476
+ if (overwrite || !discovered.has(npmPkgName)) {
80477
+ discovered.set(npmPkgName, adapterEntry);
80478
+ }
80479
+ }
80480
+ } catch {
80481
+ }
80482
+ }
80483
+ }
80484
+ async function discoverAdapters(platformRoot, projectRoot) {
80485
+ const discovered = /* @__PURE__ */ new Map();
80486
+ if (projectRoot && projectRoot !== platformRoot) {
80487
+ await loadAdaptersFromLock(
80488
+ projectRoot,
80489
+ discovered,
80490
+ /* overwrite= */
80491
+ true
80492
+ );
80493
+ }
80494
+ await loadAdaptersFromLock(
80495
+ platformRoot,
80496
+ discovered,
80497
+ /* overwrite= */
80498
+ false
80499
+ );
80500
+ return discovered;
80501
+ }
80502
+ async function resolveAdapter(adapterPath, cwd, platformRoot) {
80503
+ const discovered = await discoverAdapters(
80504
+ platformRoot ?? cwd,
80505
+ platformRoot && platformRoot !== cwd ? cwd : void 0
80506
+ );
80507
+ const basePkgName = adapterPath.split("/").slice(0, 2).join("/");
80508
+ const subpath = adapterPath.includes("/") ? adapterPath.split("/").slice(2).join("/") : null;
80509
+ const adapter = discovered.get(basePkgName);
80510
+ if (adapter && subpath) {
80511
+ const subpathFile = path13__namespace.default.join(adapter.pkgRoot, "dist", `${subpath}.js`);
80512
+ try {
80513
+ await fs5.promises.access(subpathFile);
80514
+ const module = await loadAdapterModule(subpathFile);
80515
+ if (typeof module.createAdapter === "function") {
80516
+ return module.createAdapter;
80517
+ }
80518
+ if (typeof module.default === "function") {
80519
+ return module.default;
80520
+ }
80521
+ } catch {
80522
+ }
80523
+ } else if (adapter) {
80524
+ return adapter.createAdapter;
80525
+ }
80526
+ return null;
80527
+ }
80528
+ var init_discover_adapters = __esm3({
80529
+ "src/discover-adapters.ts"() {
81473
80530
  }
81474
80531
  });
81475
80532
  var config_adapter_exports = {};
@@ -81545,6 +80602,122 @@ var init_config_adapter = __esm3({
81545
80602
  };
81546
80603
  }
81547
80604
  });
80605
+ var BulkTransferHelper2;
80606
+ var init_bulk_transfer = __esm3({
80607
+ "src/transport/bulk-transfer.ts"() {
80608
+ BulkTransferHelper2 = class _BulkTransferHelper2 {
80609
+ /** Map of temp file IDs to file paths (for cleanup) */
80610
+ static tempFiles = /* @__PURE__ */ new Map();
80611
+ /** Default options */
80612
+ static defaultOptions = {
80613
+ maxInlineSize: 1e6,
80614
+ // 1MB
80615
+ tempDir: os4.tmpdir()
80616
+ };
80617
+ /**
80618
+ * Serialize data: inline for small, temp file for large
80619
+ *
80620
+ * @example
80621
+ * ```typescript
80622
+ * const transfer = await BulkTransferHelper.serialize(vectors, {
80623
+ * maxInlineSize: 1_000_000,
80624
+ * tempDir: '/tmp'
80625
+ * });
80626
+ *
80627
+ * if (transfer.type === 'inline') {
80628
+ * console.log('Using inline IPC');
80629
+ * } else {
80630
+ * console.log('Using temp file:', transfer.payload); // Absolute path like '/tmp/bulk-123.json'
80631
+ * }
80632
+ * ```
80633
+ */
80634
+ static async serialize(data, options = {}) {
80635
+ const opts = { ...this.defaultOptions, ...options };
80636
+ const json3 = JSON.stringify(data);
80637
+ if (json3.length < opts.maxInlineSize) {
80638
+ return { type: "inline", payload: json3 };
80639
+ }
80640
+ const tempId = `bulk-${Date.now()}-${Math.random().toString(36).slice(2)}`;
80641
+ const tempPath = path13.join(opts.tempDir, `${tempId}.json`);
80642
+ await fs2.writeFile(tempPath, json3, "utf8");
80643
+ this.tempFiles.set(tempPath, tempPath);
80644
+ return { type: "file", payload: tempPath };
80645
+ }
80646
+ /**
80647
+ * Deserialize from inline JSON or temp file
80648
+ *
80649
+ * @example
80650
+ * ```typescript
80651
+ * const transfer = { type: 'file', payload: '/tmp/bulk-123.json' };
80652
+ * const data = await BulkTransferHelper.deserialize<VectorRecord[]>(transfer);
80653
+ * ```
80654
+ */
80655
+ static async deserialize(transfer) {
80656
+ if (transfer.type === "inline") {
80657
+ return JSON.parse(transfer.payload);
80658
+ }
80659
+ const tempPath = transfer.payload;
80660
+ try {
80661
+ const json3 = await fs2.readFile(tempPath, "utf8");
80662
+ return JSON.parse(json3);
80663
+ } finally {
80664
+ await fs2.unlink(tempPath).catch(() => {
80665
+ });
80666
+ this.tempFiles.delete(tempPath);
80667
+ }
80668
+ }
80669
+ /**
80670
+ * Check if object is a BulkTransfer
80671
+ */
80672
+ static isBulkTransfer(obj) {
80673
+ return typeof obj === "object" && obj !== null && "type" in obj && "payload" in obj && (obj.type === "inline" || obj.type === "file");
80674
+ }
80675
+ /**
80676
+ * Cleanup all temp files (call on process exit)
80677
+ */
80678
+ static async cleanup() {
80679
+ const cleanupPromises = Array.from(this.tempFiles.values()).map(
80680
+ (path62) => fs2.unlink(path62).catch(() => {
80681
+ })
80682
+ );
80683
+ await Promise.all(cleanupPromises);
80684
+ this.tempFiles.clear();
80685
+ }
80686
+ /**
80687
+ * Get statistics about temp files
80688
+ */
80689
+ static getStats() {
80690
+ return {
80691
+ tempFilesCount: this.tempFiles.size,
80692
+ tempFilePaths: Array.from(this.tempFiles.values())
80693
+ };
80694
+ }
80695
+ static registerSignalHandlers() {
80696
+ process.on("SIGINT", async () => {
80697
+ await _BulkTransferHelper2.cleanup();
80698
+ process.exit(0);
80699
+ });
80700
+ process.on("SIGTERM", async () => {
80701
+ await _BulkTransferHelper2.cleanup();
80702
+ process.exit(0);
80703
+ });
80704
+ process.on("uncaughtException", async (error2) => {
80705
+ console.error("[BulkTransferHelper] Uncaught exception, cleaning up temp files:", error2);
80706
+ await _BulkTransferHelper2.cleanup();
80707
+ process.exit(1);
80708
+ });
80709
+ }
80710
+ };
80711
+ process.on("exit", () => {
80712
+ for (const path62 of BulkTransferHelper2.getStats().tempFilePaths) {
80713
+ try {
80714
+ fs5.unlinkSync(path62);
80715
+ } catch {
80716
+ }
80717
+ }
80718
+ });
80719
+ }
80720
+ });
81548
80721
  var unix_socket_server_exports = {};
81549
80722
  __export3(unix_socket_server_exports, {
81550
80723
  UnixSocketServer: () => UnixSocketServer2,
@@ -84218,35 +83391,37 @@ async function initPlatform(config2 = {}, cwd = process.cwd(), uiProvider, platf
84218
83391
  try {
84219
83392
  if (isChildProcess) {
84220
83393
  platform.logger.debug("initPlatform child process detected - creating proxy adapters");
84221
- const { UnixSocketTransport: UnixSocketTransport3 } = await Promise.resolve().then(() => (init_unix_socket_transport(), unix_socket_transport_exports));
84222
- const { VectorStoreProxy: VectorStoreProxy22 } = await Promise.resolve().then(() => (init_vector_store_proxy(), vector_store_proxy_exports));
84223
- const { CacheProxy: CacheProxy22 } = await Promise.resolve().then(() => (init_cache_proxy(), cache_proxy_exports));
84224
- const { ConfigProxy: ConfigProxy22 } = await Promise.resolve().then(() => (init_config_proxy(), config_proxy_exports));
84225
- const { LLMProxy: LLMProxy22 } = await Promise.resolve().then(() => (init_llm_proxy(), llm_proxy_exports));
84226
- const { EmbeddingsProxy: EmbeddingsProxy22 } = await Promise.resolve().then(() => (init_embeddings_proxy(), embeddings_proxy_exports));
84227
- const { StorageProxy: StorageProxy22 } = await Promise.resolve().then(() => (init_storage_proxy(), storage_proxy_exports));
83394
+ const {
83395
+ UnixSocketTransport: UnixSocketTransport3,
83396
+ VectorStoreProxy: VectorStoreProxy2,
83397
+ CacheProxy: CacheProxy2,
83398
+ ConfigProxy: ConfigProxy2,
83399
+ LLMProxy: LLMProxy2,
83400
+ EmbeddingsProxy: EmbeddingsProxy2,
83401
+ StorageProxy: StorageProxy2
83402
+ } = await Promise.resolve().then(() => (init_dist5(), dist_exports));
84228
83403
  const transport = new UnixSocketTransport3();
84229
83404
  platform.logger.debug("initPlatform using Unix Socket transport");
84230
83405
  if (adapters.vectorStore) {
84231
- platform.setAdapter("vectorStore", new VectorStoreProxy22(transport));
83406
+ platform.setAdapter("vectorStore", new VectorStoreProxy2(transport));
84232
83407
  platform.logger.debug("initPlatform created VectorStoreProxy");
84233
83408
  }
84234
83409
  if (adapters.cache) {
84235
- platform.setAdapter("cache", new CacheProxy22(transport));
83410
+ platform.setAdapter("cache", new CacheProxy2(transport));
84236
83411
  platform.logger.debug("initPlatform created CacheProxy");
84237
83412
  }
84238
- platform.setAdapter("config", new ConfigProxy22(transport));
83413
+ platform.setAdapter("config", new ConfigProxy2(transport));
84239
83414
  platform.logger.debug("initPlatform created ConfigProxy");
84240
- platform.setAdapter("llm", new LLMProxy22(transport));
83415
+ platform.setAdapter("llm", new LLMProxy2(transport));
84241
83416
  platform.logger.debug("initPlatform created LLMProxy");
84242
83417
  if (adapters.embeddings) {
84243
- const embeddingsProxy = new EmbeddingsProxy22(transport);
83418
+ const embeddingsProxy = new EmbeddingsProxy2(transport);
84244
83419
  await embeddingsProxy.getDimensions();
84245
83420
  platform.setAdapter("embeddings", embeddingsProxy);
84246
83421
  platform.logger.debug("initPlatform created EmbeddingsProxy");
84247
83422
  }
84248
83423
  if (adapters.storage) {
84249
- platform.setAdapter("storage", new StorageProxy22(transport));
83424
+ platform.setAdapter("storage", new StorageProxy2(transport));
84250
83425
  platform.logger.debug("initPlatform created StorageProxy");
84251
83426
  }
84252
83427
  fillAdapterFallbacksAndRecord(
@@ -84941,6 +84116,47 @@ function interpolateConfig(value, required2 = true, env = process.env) {
84941
84116
  }
84942
84117
  return value;
84943
84118
  }
84119
+ function applyLocalNetworkOffset(value, env = process.env) {
84120
+ const offset = Number(env.KB_NET_OFFSET) || 0;
84121
+ if (offset === 0) {
84122
+ return value;
84123
+ }
84124
+ return shiftConfigUrls(value, offset);
84125
+ }
84126
+ function shiftConfigUrls(value, offset) {
84127
+ if (typeof value === "string") {
84128
+ return shiftLoopbackUrl(value, offset);
84129
+ }
84130
+ if (Array.isArray(value)) {
84131
+ return value.map((item) => shiftConfigUrls(item, offset));
84132
+ }
84133
+ if (value === null || typeof value !== "object") {
84134
+ return value;
84135
+ }
84136
+ const result = {};
84137
+ for (const [key, child] of Object.entries(value)) {
84138
+ result[key] = key === "serviceTransport" ? child : shiftConfigUrls(child, offset);
84139
+ }
84140
+ return result;
84141
+ }
84142
+ function shiftLoopbackUrl(value, offset) {
84143
+ let url2;
84144
+ try {
84145
+ url2 = new URL(value);
84146
+ } catch {
84147
+ return value;
84148
+ }
84149
+ if (!["localhost", "127.0.0.1", "::1", "[::1]"].includes(url2.hostname) || !url2.port) {
84150
+ return value;
84151
+ }
84152
+ const port = Number(url2.port);
84153
+ if (!Number.isInteger(port) || port <= 0) {
84154
+ return value;
84155
+ }
84156
+ url2.port = String(port + offset);
84157
+ const shifted = url2.toString();
84158
+ return /^[a-z][a-z0-9+.-]*:\/\/[^/?#]+$/i.test(value) ? shifted.replace(/\/$/, "") : shifted;
84159
+ }
84944
84160
  var PLATFORM_CONFIG_PRODUCT = "platform";
84945
84161
  var PLATFORM_CONFIG_SCHEMA = {
84946
84162
  type: "object",
@@ -85117,7 +84333,10 @@ async function loadPlatformConfig(options = {}) {
85117
84333
  );
85118
84334
  }
85119
84335
  const strictInterpolation = env.NODE_ENV === "production";
85120
- const effective = interpolateConfig(merged, strictInterpolation, env);
84336
+ const effective = applyLocalNetworkOffset(
84337
+ interpolateConfig(merged, strictInterpolation, env),
84338
+ env
84339
+ );
85121
84340
  return {
85122
84341
  platformConfig: effective,
85123
84342
  rawConfig: rawProjectConfig,
@@ -85549,21 +84768,7 @@ function createSilentLogger() {
85549
84768
  debug: noop
85550
84769
  };
85551
84770
  }
85552
- init_remote_adapter();
85553
- init_vector_store_proxy();
85554
- init_cache_proxy();
85555
- init_llm_proxy();
85556
- init_embeddings_proxy();
85557
- init_storage_proxy();
85558
- init_remote_adapter();
85559
- init_remote_adapter();
85560
- init_unix_socket_transport();
85561
- init_cache_proxy();
85562
- init_llm_proxy();
85563
- init_embeddings_proxy();
85564
- init_vector_store_proxy();
85565
- init_storage_proxy();
85566
- init_remote_adapter();
84771
+ init_bulk_transfer();
85567
84772
  init_container();
85568
84773
  init_adapter_status();
85569
84774