@qwickapps/qwickbrain-proxy 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/db/schema.d.ts +63 -6
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +17 -2
- package/dist/db/schema.js.map +1 -1
- package/dist/lib/__tests__/cache-manager.test.js +146 -83
- package/dist/lib/__tests__/cache-manager.test.js.map +1 -1
- package/dist/lib/__tests__/connection-manager.test.js +2 -2
- package/dist/lib/__tests__/connection-manager.test.js.map +1 -1
- package/dist/lib/__tests__/proxy-server.test.js +16 -44
- package/dist/lib/__tests__/proxy-server.test.js.map +1 -1
- package/dist/lib/__tests__/qwickbrain-client.test.js +3 -1
- package/dist/lib/__tests__/qwickbrain-client.test.js.map +1 -1
- package/dist/lib/__tests__/sse-invalidation-listener.test.d.ts +2 -0
- package/dist/lib/__tests__/sse-invalidation-listener.test.d.ts.map +1 -0
- package/dist/lib/__tests__/sse-invalidation-listener.test.js +245 -0
- package/dist/lib/__tests__/sse-invalidation-listener.test.js.map +1 -0
- package/dist/lib/__tests__/write-queue-manager.test.d.ts +2 -0
- package/dist/lib/__tests__/write-queue-manager.test.d.ts.map +1 -0
- package/dist/lib/__tests__/write-queue-manager.test.js +291 -0
- package/dist/lib/__tests__/write-queue-manager.test.js.map +1 -0
- package/dist/lib/cache-manager.d.ts +35 -6
- package/dist/lib/cache-manager.d.ts.map +1 -1
- package/dist/lib/cache-manager.js +154 -41
- package/dist/lib/cache-manager.js.map +1 -1
- package/dist/lib/connection-manager.d.ts +7 -0
- package/dist/lib/connection-manager.d.ts.map +1 -1
- package/dist/lib/connection-manager.js +57 -8
- package/dist/lib/connection-manager.js.map +1 -1
- package/dist/lib/proxy-server.d.ts +12 -0
- package/dist/lib/proxy-server.d.ts.map +1 -1
- package/dist/lib/proxy-server.js +184 -87
- package/dist/lib/proxy-server.js.map +1 -1
- package/dist/lib/qwickbrain-client.d.ts +4 -0
- package/dist/lib/qwickbrain-client.d.ts.map +1 -1
- package/dist/lib/qwickbrain-client.js +152 -13
- package/dist/lib/qwickbrain-client.js.map +1 -1
- package/dist/lib/sse-invalidation-listener.d.ts +31 -0
- package/dist/lib/sse-invalidation-listener.d.ts.map +1 -0
- package/dist/lib/sse-invalidation-listener.js +151 -0
- package/dist/lib/sse-invalidation-listener.js.map +1 -0
- package/dist/lib/tools.d.ts +21 -0
- package/dist/lib/tools.d.ts.map +1 -0
- package/dist/lib/tools.js +513 -0
- package/dist/lib/tools.js.map +1 -0
- package/dist/lib/write-queue-manager.d.ts +88 -0
- package/dist/lib/write-queue-manager.d.ts.map +1 -0
- package/dist/lib/write-queue-manager.js +191 -0
- package/dist/lib/write-queue-manager.js.map +1 -0
- package/dist/types/config.d.ts +7 -42
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +1 -6
- package/dist/types/config.js.map +1 -1
- package/drizzle/0002_lru_cache_migration.sql +94 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +6 -2
- package/scripts/rebuild-sqlite.sh +26 -0
- package/src/db/schema.ts +17 -2
- package/src/lib/__tests__/cache-manager.test.ts +180 -90
- package/src/lib/__tests__/connection-manager.test.ts +2 -2
- package/src/lib/__tests__/proxy-server.test.ts +16 -51
- package/src/lib/__tests__/qwickbrain-client.test.ts +3 -1
- package/src/lib/__tests__/sse-invalidation-listener.test.ts +326 -0
- package/src/lib/__tests__/write-queue-manager.test.ts +383 -0
- package/src/lib/cache-manager.ts +198 -46
- package/src/lib/connection-manager.ts +67 -8
- package/src/lib/proxy-server.ts +231 -90
- package/src/lib/qwickbrain-client.ts +166 -12
- package/src/lib/sse-invalidation-listener.ts +185 -0
- package/src/lib/tools.ts +525 -0
- package/src/lib/write-queue-manager.ts +271 -0
- package/src/types/config.ts +1 -6
- package/.github/workflows/publish.yml +0 -92
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache-manager.js","sourceRoot":"","sources":["../../src/lib/cache-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"cache-manager.js","sourceRoot":"","sources":["../../src/lib/cache-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,7 @@ export declare class ConnectionManager extends EventEmitter {
|
|
|
10
10
|
private qwickbrainClient;
|
|
11
11
|
private config;
|
|
12
12
|
private isStopped;
|
|
13
|
+
private isDormant;
|
|
13
14
|
private executionLock;
|
|
14
15
|
constructor(qwickbrainClient: QwickBrainClient, config: Config['connection']);
|
|
15
16
|
getState(): ConnectionState;
|
|
@@ -19,6 +20,12 @@ export declare class ConnectionManager extends EventEmitter {
|
|
|
19
20
|
healthCheck(): Promise<boolean>;
|
|
20
21
|
private scheduleHealthCheck;
|
|
21
22
|
private scheduleReconnect;
|
|
23
|
+
private enterDormantMode;
|
|
24
|
+
/**
|
|
25
|
+
* Wake from dormant mode and attempt immediate reconnection.
|
|
26
|
+
* Called when a tool is invoked and we need to try connecting again.
|
|
27
|
+
*/
|
|
28
|
+
wakeUp(): void;
|
|
22
29
|
private clearReconnectTimer;
|
|
23
30
|
recordFailure(): void;
|
|
24
31
|
execute<T>(fn: () => Promise<T>): Promise<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-manager.d.ts","sourceRoot":"","sources":["../../src/lib/connection-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"connection-manager.d.ts","sourceRoot":"","sources":["../../src/lib/connection-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAK/D,qBAAa,iBAAkB,SAAQ,YAAY;IACjD,OAAO,CAAC,KAAK,CAAmC;IAChD,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAoC;gBAE7C,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,CAAC,YAAY,CAAC;IAM5E,QAAQ,IAAI,eAAe;IAI3B,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAShC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAU5B,IAAI,IAAI,IAAI;IAcN,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAkCrC,OAAO,CAAC,mBAAmB;IAmB3B,OAAO,CAAC,iBAAiB;IA2BzB,OAAO,CAAC,gBAAgB;IAoBxB;;;OAGG;IACH,MAAM,IAAI,IAAI;IAqBd,OAAO,CAAC,mBAAmB;IAO3B,aAAa,IAAI,IAAI;IAOf,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAgBnD"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
+
// Dormant mode: long interval health check after giving up on reconnection
|
|
3
|
+
const DORMANT_CHECK_INTERVAL = 300000; // 5 minutes
|
|
2
4
|
export class ConnectionManager extends EventEmitter {
|
|
3
5
|
state = 'disconnected';
|
|
4
6
|
reconnectAttempts = 0;
|
|
@@ -7,6 +9,7 @@ export class ConnectionManager extends EventEmitter {
|
|
|
7
9
|
qwickbrainClient;
|
|
8
10
|
config;
|
|
9
11
|
isStopped = false;
|
|
12
|
+
isDormant = false;
|
|
10
13
|
executionLock = Promise.resolve();
|
|
11
14
|
constructor(qwickbrainClient, config) {
|
|
12
15
|
super();
|
|
@@ -25,6 +28,7 @@ export class ConnectionManager extends EventEmitter {
|
|
|
25
28
|
}
|
|
26
29
|
async start() {
|
|
27
30
|
this.isStopped = false;
|
|
31
|
+
this.isDormant = false;
|
|
28
32
|
// Start health check in background (don't block server startup)
|
|
29
33
|
this.healthCheck().catch(err => {
|
|
30
34
|
console.error('Initial health check error:', err);
|
|
@@ -33,6 +37,7 @@ export class ConnectionManager extends EventEmitter {
|
|
|
33
37
|
}
|
|
34
38
|
stop() {
|
|
35
39
|
this.isStopped = true;
|
|
40
|
+
this.isDormant = false;
|
|
36
41
|
if (this.healthCheckTimer) {
|
|
37
42
|
clearTimeout(this.healthCheckTimer);
|
|
38
43
|
this.healthCheckTimer = null;
|
|
@@ -49,10 +54,16 @@ export class ConnectionManager extends EventEmitter {
|
|
|
49
54
|
const isHealthy = await this.qwickbrainClient.healthCheck();
|
|
50
55
|
const latencyMs = Date.now() - startTime;
|
|
51
56
|
if (isHealthy) {
|
|
57
|
+
const wasDormant = this.isDormant;
|
|
58
|
+
this.isDormant = false;
|
|
52
59
|
this.setState('connected');
|
|
53
60
|
this.reconnectAttempts = 0;
|
|
54
61
|
this.clearReconnectTimer();
|
|
55
62
|
this.emit('connected', { latencyMs });
|
|
63
|
+
// If waking from dormant, switch back to normal health check interval
|
|
64
|
+
if (wasDormant) {
|
|
65
|
+
this.scheduleHealthCheck();
|
|
66
|
+
}
|
|
56
67
|
return true;
|
|
57
68
|
}
|
|
58
69
|
else {
|
|
@@ -61,35 +72,35 @@ export class ConnectionManager extends EventEmitter {
|
|
|
61
72
|
}
|
|
62
73
|
catch (error) {
|
|
63
74
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
64
|
-
this.
|
|
65
|
-
|
|
66
|
-
|
|
75
|
+
if (!this.isDormant) {
|
|
76
|
+
this.setState('disconnected');
|
|
77
|
+
this.emit('disconnected', { error: errorMessage });
|
|
78
|
+
this.scheduleReconnect();
|
|
79
|
+
}
|
|
67
80
|
return false;
|
|
68
81
|
}
|
|
69
82
|
}
|
|
70
83
|
scheduleHealthCheck() {
|
|
71
|
-
// Don't schedule if stopped
|
|
72
84
|
if (this.isStopped) {
|
|
73
85
|
return;
|
|
74
86
|
}
|
|
75
87
|
if (this.healthCheckTimer) {
|
|
76
88
|
clearTimeout(this.healthCheckTimer);
|
|
77
89
|
}
|
|
90
|
+
const interval = this.isDormant ? DORMANT_CHECK_INTERVAL : this.config.healthCheckInterval;
|
|
78
91
|
this.healthCheckTimer = setTimeout(async () => {
|
|
79
92
|
await this.healthCheck();
|
|
80
|
-
// Check again before rescheduling to prevent leak after stop()
|
|
81
93
|
if (!this.isStopped) {
|
|
82
94
|
this.scheduleHealthCheck();
|
|
83
95
|
}
|
|
84
|
-
},
|
|
96
|
+
}, interval);
|
|
85
97
|
}
|
|
86
98
|
scheduleReconnect() {
|
|
87
99
|
if (this.reconnectTimer) {
|
|
88
100
|
return; // Already scheduled
|
|
89
101
|
}
|
|
90
102
|
if (this.reconnectAttempts >= this.config.maxReconnectAttempts) {
|
|
91
|
-
this.
|
|
92
|
-
this.emit('maxReconnectAttemptsReached');
|
|
103
|
+
this.enterDormantMode();
|
|
93
104
|
return;
|
|
94
105
|
}
|
|
95
106
|
const delay = Math.min(this.config.reconnectBackoff.initial *
|
|
@@ -102,6 +113,44 @@ export class ConnectionManager extends EventEmitter {
|
|
|
102
113
|
}, delay);
|
|
103
114
|
this.emit('reconnecting', { attempt: this.reconnectAttempts, delay });
|
|
104
115
|
}
|
|
116
|
+
enterDormantMode() {
|
|
117
|
+
this.isDormant = true;
|
|
118
|
+
this.setState('offline');
|
|
119
|
+
this.emit('dormant');
|
|
120
|
+
// Stop active health check and reconnect timers
|
|
121
|
+
if (this.healthCheckTimer) {
|
|
122
|
+
clearTimeout(this.healthCheckTimer);
|
|
123
|
+
this.healthCheckTimer = null;
|
|
124
|
+
}
|
|
125
|
+
if (this.reconnectTimer) {
|
|
126
|
+
clearTimeout(this.reconnectTimer);
|
|
127
|
+
this.reconnectTimer = null;
|
|
128
|
+
}
|
|
129
|
+
// Schedule dormant-mode health check (5 min interval)
|
|
130
|
+
console.error(`Entering dormant mode. Will retry every ${DORMANT_CHECK_INTERVAL / 1000}s.`);
|
|
131
|
+
this.scheduleHealthCheck();
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Wake from dormant mode and attempt immediate reconnection.
|
|
135
|
+
* Called when a tool is invoked and we need to try connecting again.
|
|
136
|
+
*/
|
|
137
|
+
wakeUp() {
|
|
138
|
+
if (!this.isDormant || this.isStopped) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
console.error('Waking from dormant mode for tool call...');
|
|
142
|
+
this.isDormant = false;
|
|
143
|
+
this.reconnectAttempts = 0;
|
|
144
|
+
// Clear dormant timer and do immediate health check
|
|
145
|
+
if (this.healthCheckTimer) {
|
|
146
|
+
clearTimeout(this.healthCheckTimer);
|
|
147
|
+
this.healthCheckTimer = null;
|
|
148
|
+
}
|
|
149
|
+
this.healthCheck().catch(err => {
|
|
150
|
+
console.error('Wake-up health check error:', err);
|
|
151
|
+
});
|
|
152
|
+
this.scheduleHealthCheck();
|
|
153
|
+
}
|
|
105
154
|
clearReconnectTimer() {
|
|
106
155
|
if (this.reconnectTimer) {
|
|
107
156
|
clearTimeout(this.reconnectTimer);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-manager.js","sourceRoot":"","sources":["../../src/lib/connection-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKtC,MAAM,OAAO,iBAAkB,SAAQ,YAAY;IACzC,KAAK,GAAoB,cAAc,CAAC;IACxC,iBAAiB,GAAG,CAAC,CAAC;IACtB,cAAc,GAA0B,IAAI,CAAC;IAC7C,gBAAgB,GAA0B,IAAI,CAAC;IAC/C,gBAAgB,CAAmB;IACnC,MAAM,CAAuB;IAC7B,SAAS,GAAG,KAAK,CAAC;IAClB,aAAa,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAEzD,YAAY,gBAAkC,EAAE,MAA4B;QAC1E,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,QAAQ,CAAC,KAAsB;QAC7B,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QAEnB,IAAI,aAAa,KAAK,KAAK,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,gEAAgE;QAChE,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YAC7B,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI;QACF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACpC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC/B,CAAC;QACD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC;YAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAEzC,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAC3B,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;gBAC3B,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"connection-manager.js","sourceRoot":"","sources":["../../src/lib/connection-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAKtC,2EAA2E;AAC3E,MAAM,sBAAsB,GAAG,MAAM,CAAC,CAAC,YAAY;AAEnD,MAAM,OAAO,iBAAkB,SAAQ,YAAY;IACzC,KAAK,GAAoB,cAAc,CAAC;IACxC,iBAAiB,GAAG,CAAC,CAAC;IACtB,cAAc,GAA0B,IAAI,CAAC;IAC7C,gBAAgB,GAA0B,IAAI,CAAC;IAC/C,gBAAgB,CAAmB;IACnC,MAAM,CAAuB;IAC7B,SAAS,GAAG,KAAK,CAAC;IAClB,SAAS,GAAG,KAAK,CAAC;IAClB,aAAa,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAEzD,YAAY,gBAAkC,EAAE,MAA4B;QAC1E,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,QAAQ,CAAC,KAAsB;QAC7B,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QAEnB,IAAI,aAAa,KAAK,KAAK,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,gEAAgE;QAChE,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YAC7B,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI;QACF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACpC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC/B,CAAC;QACD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC;YAC5D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAEzC,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;gBAClC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;gBACvB,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAC3B,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;gBAC3B,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;gBAEtC,sEAAsE;gBACtE,IAAI,UAAU,EAAE,CAAC;oBACf,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC7B,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,YAAY,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5E,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;gBAC9B,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;gBACnD,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAEO,mBAAmB;QACzB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACtC,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC;QAE3F,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;YAC5C,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpB,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC7B,CAAC;QACH,CAAC,EAAE,QAAQ,CAAC,CAAC;IACf,CAAC;IAEO,iBAAiB;QACvB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,OAAO,CAAC,oBAAoB;QAC9B,CAAC;QAED,IAAI,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC;YAC/D,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO;YAClC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,iBAAiB,CAAC,EAC3E,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,CACjC,CAAC;QAEF,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;QAE9B,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;YAC1C,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QAC3B,CAAC,EAAE,KAAK,CAAC,CAAC;QAEV,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,KAAK,EAAE,CAAC,CAAC;IACxE,CAAC;IAEO,gBAAgB;QACtB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAErB,gDAAgD;QAChD,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACpC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC/B,CAAC;QACD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;QAED,sDAAsD;QACtD,OAAO,CAAC,KAAK,CAAC,2CAA2C,sBAAsB,GAAG,IAAI,IAAI,CAAC,CAAC;QAC5F,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACH,MAAM;QACJ,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,OAAO;QACT,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC3D,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAE3B,oDAAoD;QACpD,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACpC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC/B,CAAC;QAED,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YAC7B,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAEO,mBAAmB;QACzB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,aAAa;QACX,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;YAC9B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO,CAAI,EAAoB;QACnC,qDAAqD;QACrD,MAAM,IAAI,CAAC,aAAa,CAAC;QAEzB,qCAAqC;QACrC,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,kCAAkC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACnE,CAAC;QAED,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
|
|
@@ -5,15 +5,27 @@ export declare class ProxyServer {
|
|
|
5
5
|
private connectionManager;
|
|
6
6
|
private cacheManager;
|
|
7
7
|
private qwickbrainClient;
|
|
8
|
+
private writeQueueManager;
|
|
9
|
+
private sseInvalidationListener;
|
|
8
10
|
private config;
|
|
11
|
+
private connectionInitialized;
|
|
9
12
|
constructor(db: DB, config: Config);
|
|
13
|
+
/**
|
|
14
|
+
* Lazy initialization: start connection manager on first tool call
|
|
15
|
+
* instead of eagerly on server startup. Saves CPU when QwickBrain
|
|
16
|
+
* tools are never used in a session.
|
|
17
|
+
*/
|
|
18
|
+
private ensureConnectionInitialized;
|
|
10
19
|
private setupConnectionListeners;
|
|
11
20
|
private onConnectionRestored;
|
|
21
|
+
private syncWriteQueue;
|
|
12
22
|
private setupHandlers;
|
|
13
23
|
private createMetadata;
|
|
14
24
|
private handleGetWorkflow;
|
|
15
25
|
private handleGetDocument;
|
|
16
26
|
private handleGetMemory;
|
|
27
|
+
private handleCreateDocument;
|
|
28
|
+
private handleSetMemory;
|
|
17
29
|
private handleGenericTool;
|
|
18
30
|
start(): Promise<void>;
|
|
19
31
|
stop(): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy-server.d.ts","sourceRoot":"","sources":["../../src/lib/proxy-server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"proxy-server.d.ts","sourceRoot":"","sources":["../../src/lib/proxy-server.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAI1C,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,uBAAuB,CAAwC;IACvE,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,qBAAqB,CAAS;gBAE1B,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM;IAqClC;;;;OAIG;YACW,2BAA2B;IAgBzC,OAAO,CAAC,wBAAwB;YA8ClB,oBAAoB;YAsBpB,cAAc;IAW5B,OAAO,CAAC,aAAa;IAqHrB,OAAO,CAAC,cAAc;YAQR,iBAAiB;YAIjB,iBAAiB;YAwDjB,eAAe;YAyCf,oBAAoB;YA6CpB,eAAe;YA2Cf,iBAAiB;IAmDzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAYtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAgB5B"}
|
package/dist/lib/proxy-server.js
CHANGED
|
@@ -4,13 +4,19 @@ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextpro
|
|
|
4
4
|
import { ConnectionManager } from './connection-manager.js';
|
|
5
5
|
import { CacheManager } from './cache-manager.js';
|
|
6
6
|
import { QwickBrainClient } from './qwickbrain-client.js';
|
|
7
|
+
import { WriteQueueManager } from './write-queue-manager.js';
|
|
8
|
+
import { SSEInvalidationListener } from './sse-invalidation-listener.js';
|
|
9
|
+
import { QWICKBRAIN_TOOLS, requiresConnection } from './tools.js';
|
|
7
10
|
import { VERSION } from '../version.js';
|
|
8
11
|
export class ProxyServer {
|
|
9
12
|
server;
|
|
10
13
|
connectionManager;
|
|
11
14
|
cacheManager;
|
|
12
15
|
qwickbrainClient;
|
|
16
|
+
writeQueueManager;
|
|
17
|
+
sseInvalidationListener = null;
|
|
13
18
|
config;
|
|
19
|
+
connectionInitialized = false;
|
|
14
20
|
constructor(db, config) {
|
|
15
21
|
this.config = config;
|
|
16
22
|
this.server = new Server({
|
|
@@ -24,9 +30,31 @@ export class ProxyServer {
|
|
|
24
30
|
this.qwickbrainClient = new QwickBrainClient(config.qwickbrain);
|
|
25
31
|
this.connectionManager = new ConnectionManager(this.qwickbrainClient, config.connection);
|
|
26
32
|
this.cacheManager = new CacheManager(db, config.cache);
|
|
33
|
+
this.writeQueueManager = new WriteQueueManager(db, this.qwickbrainClient);
|
|
34
|
+
// Initialize SSE invalidation listener if in SSE mode
|
|
35
|
+
if (config.qwickbrain.mode === 'sse' && config.qwickbrain.url) {
|
|
36
|
+
this.sseInvalidationListener = new SSEInvalidationListener(config.qwickbrain.url, this.cacheManager, config.qwickbrain.apiKey);
|
|
37
|
+
}
|
|
27
38
|
this.setupHandlers();
|
|
28
39
|
this.setupConnectionListeners();
|
|
29
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Lazy initialization: start connection manager on first tool call
|
|
43
|
+
* instead of eagerly on server startup. Saves CPU when QwickBrain
|
|
44
|
+
* tools are never used in a session.
|
|
45
|
+
*/
|
|
46
|
+
async ensureConnectionInitialized() {
|
|
47
|
+
if (this.connectionInitialized) {
|
|
48
|
+
// If dormant, wake up on tool call
|
|
49
|
+
this.connectionManager.wakeUp();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this.connectionInitialized = true;
|
|
53
|
+
console.error('First tool call received, initializing connection...');
|
|
54
|
+
await this.connectionManager.start();
|
|
55
|
+
// SSE listener starts only when connection is established (see setupConnectionListeners)
|
|
56
|
+
// Not here - avoid starting SSE reconnection loops before we know the server is reachable
|
|
57
|
+
}
|
|
30
58
|
setupConnectionListeners() {
|
|
31
59
|
this.connectionManager.on('stateChange', ({ from, to }) => {
|
|
32
60
|
console.error(`Connection state: ${from} → ${to}`);
|
|
@@ -36,13 +64,34 @@ export class ProxyServer {
|
|
|
36
64
|
});
|
|
37
65
|
this.connectionManager.on('connected', ({ latencyMs }) => {
|
|
38
66
|
console.error(`Connected to QwickBrain (latency: ${latencyMs}ms)`);
|
|
67
|
+
// Start SSE listener when connection is established
|
|
68
|
+
if (this.sseInvalidationListener && !this.sseInvalidationListener.isListening()) {
|
|
69
|
+
this.sseInvalidationListener.start().catch(err => {
|
|
70
|
+
console.error('SSE listener start error:', err);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
39
73
|
// Event-driven: trigger background sync when connection restored
|
|
40
74
|
this.onConnectionRestored().catch(err => {
|
|
41
75
|
console.error('Background sync error:', err);
|
|
42
76
|
});
|
|
77
|
+
// Sync pending write operations
|
|
78
|
+
this.syncWriteQueue().catch(err => {
|
|
79
|
+
console.error('Write queue sync error:', err);
|
|
80
|
+
});
|
|
43
81
|
});
|
|
44
82
|
this.connectionManager.on('disconnected', ({ error }) => {
|
|
45
83
|
console.error(`Disconnected from QwickBrain: ${error}`);
|
|
84
|
+
// Stop SSE listener when disconnected to avoid independent reconnection loops
|
|
85
|
+
if (this.sseInvalidationListener) {
|
|
86
|
+
this.sseInvalidationListener.stop();
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
this.connectionManager.on('dormant', () => {
|
|
90
|
+
console.error('Connection manager entered dormant mode');
|
|
91
|
+
// Stop SSE listener in dormant mode
|
|
92
|
+
if (this.sseInvalidationListener) {
|
|
93
|
+
this.sseInvalidationListener.stop();
|
|
94
|
+
}
|
|
46
95
|
});
|
|
47
96
|
}
|
|
48
97
|
async onConnectionRestored() {
|
|
@@ -66,64 +115,24 @@ export class ProxyServer {
|
|
|
66
115
|
}
|
|
67
116
|
console.error('Background cache sync complete');
|
|
68
117
|
}
|
|
118
|
+
async syncWriteQueue() {
|
|
119
|
+
const pendingCount = await this.writeQueueManager.getPendingCount();
|
|
120
|
+
if (pendingCount === 0) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
console.error(`Syncing ${pendingCount} pending write operations...`);
|
|
124
|
+
const { synced, failed } = await this.writeQueueManager.syncPendingOperations();
|
|
125
|
+
console.error(`Write queue sync complete: ${synced} synced, ${failed} failed`);
|
|
126
|
+
}
|
|
69
127
|
setupHandlers() {
|
|
128
|
+
// Static tool listing - always returns all tools regardless of connection state
|
|
70
129
|
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
71
|
-
|
|
72
|
-
if (this.connectionManager.getState() === 'connected') {
|
|
73
|
-
try {
|
|
74
|
-
const tools = await this.connectionManager.execute(async () => {
|
|
75
|
-
return await this.qwickbrainClient.listTools();
|
|
76
|
-
});
|
|
77
|
-
return { tools };
|
|
78
|
-
}
|
|
79
|
-
catch (error) {
|
|
80
|
-
console.error('Failed to list tools from upstream:', error);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
// Fallback to minimal tool set when offline or error
|
|
84
|
-
return {
|
|
85
|
-
tools: [
|
|
86
|
-
{
|
|
87
|
-
name: 'get_workflow',
|
|
88
|
-
description: 'Get a workflow definition by name (cached)',
|
|
89
|
-
inputSchema: {
|
|
90
|
-
type: 'object',
|
|
91
|
-
properties: {
|
|
92
|
-
name: { type: 'string', description: 'Workflow name' },
|
|
93
|
-
},
|
|
94
|
-
required: ['name'],
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
name: 'get_document',
|
|
99
|
-
description: 'Get a document by name and type (cached)',
|
|
100
|
-
inputSchema: {
|
|
101
|
-
type: 'object',
|
|
102
|
-
properties: {
|
|
103
|
-
name: { type: 'string', description: 'Document name' },
|
|
104
|
-
doc_type: { type: 'string', description: 'Document type (rule, frd, design, etc.)' },
|
|
105
|
-
project: { type: 'string', description: 'Project name (optional)' },
|
|
106
|
-
},
|
|
107
|
-
required: ['name', 'doc_type'],
|
|
108
|
-
},
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
name: 'get_memory',
|
|
112
|
-
description: 'Get a memory/context document by name (cached)',
|
|
113
|
-
inputSchema: {
|
|
114
|
-
type: 'object',
|
|
115
|
-
properties: {
|
|
116
|
-
name: { type: 'string', description: 'Memory name' },
|
|
117
|
-
project: { type: 'string', description: 'Project name (optional)' },
|
|
118
|
-
},
|
|
119
|
-
required: ['name'],
|
|
120
|
-
},
|
|
121
|
-
},
|
|
122
|
-
],
|
|
123
|
-
};
|
|
130
|
+
return { tools: QWICKBRAIN_TOOLS };
|
|
124
131
|
});
|
|
125
132
|
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
126
133
|
const { name, arguments: args } = request.params;
|
|
134
|
+
// Lazy init: start connection on first tool call
|
|
135
|
+
await this.ensureConnectionInitialized();
|
|
127
136
|
try {
|
|
128
137
|
let result;
|
|
129
138
|
// Handle cacheable document tools specially
|
|
@@ -137,8 +146,43 @@ export class ProxyServer {
|
|
|
137
146
|
case 'get_memory':
|
|
138
147
|
result = await this.handleGetMemory(args?.name, args?.project);
|
|
139
148
|
break;
|
|
149
|
+
case 'create_document':
|
|
150
|
+
case 'update_document':
|
|
151
|
+
result = await this.handleCreateDocument(args?.doc_type, args?.name, args?.content, args?.project, args?.metadata);
|
|
152
|
+
break;
|
|
153
|
+
case 'set_memory':
|
|
154
|
+
case 'update_memory':
|
|
155
|
+
result = await this.handleSetMemory(args?.name, args?.content, args?.project, args?.metadata);
|
|
156
|
+
break;
|
|
140
157
|
default:
|
|
141
158
|
// Generic forwarding for all other tools (analyze_repository, search_codebase, etc.)
|
|
159
|
+
// Check if tool requires connection
|
|
160
|
+
if (requiresConnection(name) && this.connectionManager.getState() !== 'connected') {
|
|
161
|
+
// Return offline error for non-cacheable tools
|
|
162
|
+
return {
|
|
163
|
+
content: [
|
|
164
|
+
{
|
|
165
|
+
type: 'text',
|
|
166
|
+
text: JSON.stringify({
|
|
167
|
+
error: {
|
|
168
|
+
code: 'OFFLINE',
|
|
169
|
+
message: `QwickBrain offline - "${name}" requires active connection`,
|
|
170
|
+
suggestions: [
|
|
171
|
+
'Check internet connection',
|
|
172
|
+
'Wait for automatic reconnection',
|
|
173
|
+
'Cached tools (get_workflow, get_document, get_memory) work offline',
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
_metadata: {
|
|
177
|
+
source: 'cache',
|
|
178
|
+
status: this.connectionManager.getState(),
|
|
179
|
+
},
|
|
180
|
+
}, null, 2),
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
isError: true,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
142
186
|
result = await this.handleGenericTool(name, args || {});
|
|
143
187
|
break;
|
|
144
188
|
}
|
|
@@ -185,15 +229,15 @@ export class ProxyServer {
|
|
|
185
229
|
return this.handleGetDocument('workflow', name);
|
|
186
230
|
}
|
|
187
231
|
async handleGetDocument(docType, name, project) {
|
|
188
|
-
// Try cache first
|
|
232
|
+
// Try cache first (LRU cache never expires, always valid if present)
|
|
189
233
|
const cached = await this.cacheManager.getDocument(docType, name, project);
|
|
190
|
-
if (cached
|
|
234
|
+
if (cached) {
|
|
191
235
|
return {
|
|
192
236
|
data: cached.data,
|
|
193
237
|
_metadata: this.createMetadata('cache', cached.age),
|
|
194
238
|
};
|
|
195
239
|
}
|
|
196
|
-
//
|
|
240
|
+
// Not cached - try remote if connected
|
|
197
241
|
if (this.connectionManager.getState() === 'connected') {
|
|
198
242
|
try {
|
|
199
243
|
const result = await this.connectionManager.execute(async () => {
|
|
@@ -208,20 +252,10 @@ export class ProxyServer {
|
|
|
208
252
|
}
|
|
209
253
|
catch (error) {
|
|
210
254
|
console.error('Failed to fetch from QwickBrain:', error);
|
|
211
|
-
// Fall through to
|
|
255
|
+
// Fall through to error
|
|
212
256
|
}
|
|
213
257
|
}
|
|
214
|
-
//
|
|
215
|
-
if (cached) {
|
|
216
|
-
return {
|
|
217
|
-
data: cached.data,
|
|
218
|
-
_metadata: {
|
|
219
|
-
...this.createMetadata('stale_cache', cached.age),
|
|
220
|
-
warning: `QwickBrain unavailable - serving cached data (${cached.age}s old)`,
|
|
221
|
-
},
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
// No cache, no connection
|
|
258
|
+
// No cache and remote failed/unavailable
|
|
225
259
|
return {
|
|
226
260
|
error: {
|
|
227
261
|
code: 'UNAVAILABLE',
|
|
@@ -236,14 +270,15 @@ export class ProxyServer {
|
|
|
236
270
|
};
|
|
237
271
|
}
|
|
238
272
|
async handleGetMemory(name, project) {
|
|
239
|
-
//
|
|
273
|
+
// Try cache first (LRU cache never expires, always valid if present)
|
|
240
274
|
const cached = await this.cacheManager.getMemory(name, project);
|
|
241
|
-
if (cached
|
|
275
|
+
if (cached) {
|
|
242
276
|
return {
|
|
243
277
|
data: cached.data,
|
|
244
278
|
_metadata: this.createMetadata('cache', cached.age),
|
|
245
279
|
};
|
|
246
280
|
}
|
|
281
|
+
// Not cached - try remote if connected
|
|
247
282
|
if (this.connectionManager.getState() === 'connected') {
|
|
248
283
|
try {
|
|
249
284
|
const result = await this.connectionManager.execute(async () => {
|
|
@@ -257,17 +292,10 @@ export class ProxyServer {
|
|
|
257
292
|
}
|
|
258
293
|
catch (error) {
|
|
259
294
|
console.error('Failed to fetch memory from QwickBrain:', error);
|
|
295
|
+
// Fall through to error
|
|
260
296
|
}
|
|
261
297
|
}
|
|
262
|
-
|
|
263
|
-
return {
|
|
264
|
-
data: cached.data,
|
|
265
|
-
_metadata: {
|
|
266
|
-
...this.createMetadata('stale_cache', cached.age),
|
|
267
|
-
warning: `QwickBrain unavailable - serving cached memory (${cached.age}s old)`,
|
|
268
|
-
},
|
|
269
|
-
};
|
|
270
|
-
}
|
|
298
|
+
// No cache and remote failed/unavailable
|
|
271
299
|
return {
|
|
272
300
|
error: {
|
|
273
301
|
code: 'UNAVAILABLE',
|
|
@@ -277,6 +305,75 @@ export class ProxyServer {
|
|
|
277
305
|
_metadata: this.createMetadata('cache'),
|
|
278
306
|
};
|
|
279
307
|
}
|
|
308
|
+
async handleCreateDocument(docType, name, content, project, metadata) {
|
|
309
|
+
// Always update local cache first
|
|
310
|
+
await this.cacheManager.setDocument(docType, name, content, project, metadata);
|
|
311
|
+
// If connected, sync immediately
|
|
312
|
+
if (this.connectionManager.getState() === 'connected') {
|
|
313
|
+
try {
|
|
314
|
+
await this.connectionManager.execute(async () => {
|
|
315
|
+
await this.qwickbrainClient.createDocument(docType, name, content, project, metadata);
|
|
316
|
+
});
|
|
317
|
+
return {
|
|
318
|
+
data: { success: true },
|
|
319
|
+
_metadata: this.createMetadata('live'),
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
catch (error) {
|
|
323
|
+
console.error('Failed to create document on QwickBrain:', error);
|
|
324
|
+
// Fall through to queue
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
// If offline or sync failed, queue for later
|
|
328
|
+
await this.writeQueueManager.queueOperation('create_document', {
|
|
329
|
+
docType,
|
|
330
|
+
name,
|
|
331
|
+
content,
|
|
332
|
+
project,
|
|
333
|
+
metadata,
|
|
334
|
+
});
|
|
335
|
+
return {
|
|
336
|
+
data: { success: true, queued: true },
|
|
337
|
+
_metadata: {
|
|
338
|
+
...this.createMetadata('cache'),
|
|
339
|
+
warning: 'Operation queued - will sync when connection restored',
|
|
340
|
+
},
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
async handleSetMemory(name, content, project, metadata) {
|
|
344
|
+
// Always update local cache first
|
|
345
|
+
await this.cacheManager.setMemory(name, content, project, metadata);
|
|
346
|
+
// If connected, sync immediately
|
|
347
|
+
if (this.connectionManager.getState() === 'connected') {
|
|
348
|
+
try {
|
|
349
|
+
await this.connectionManager.execute(async () => {
|
|
350
|
+
await this.qwickbrainClient.setMemory(name, content, project, metadata);
|
|
351
|
+
});
|
|
352
|
+
return {
|
|
353
|
+
data: { success: true },
|
|
354
|
+
_metadata: this.createMetadata('live'),
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
catch (error) {
|
|
358
|
+
console.error('Failed to set memory on QwickBrain:', error);
|
|
359
|
+
// Fall through to queue
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// If offline or sync failed, queue for later
|
|
363
|
+
await this.writeQueueManager.queueOperation('set_memory', {
|
|
364
|
+
name,
|
|
365
|
+
content,
|
|
366
|
+
project,
|
|
367
|
+
metadata,
|
|
368
|
+
});
|
|
369
|
+
return {
|
|
370
|
+
data: { success: true, queued: true },
|
|
371
|
+
_metadata: {
|
|
372
|
+
...this.createMetadata('cache'),
|
|
373
|
+
warning: 'Operation queued - will sync when connection restored',
|
|
374
|
+
},
|
|
375
|
+
};
|
|
376
|
+
}
|
|
280
377
|
async handleGenericTool(name, args) {
|
|
281
378
|
// Generic tool forwarding - no caching for non-document tools
|
|
282
379
|
if (this.connectionManager.getState() !== 'connected') {
|
|
@@ -326,20 +423,20 @@ export class ProxyServer {
|
|
|
326
423
|
}
|
|
327
424
|
}
|
|
328
425
|
async start() {
|
|
329
|
-
//
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
console.error(`Cache cleanup: removed ${documentsDeleted} documents, ${memoriesDeleted} memories`);
|
|
333
|
-
}
|
|
334
|
-
// Start connection manager (handles connection gracefully, doesn't throw)
|
|
335
|
-
await this.connectionManager.start();
|
|
426
|
+
// Lazy init: do NOT start connection manager here.
|
|
427
|
+
// Connection is initialized on first tool call (see ensureConnectionInitialized).
|
|
428
|
+
// This means idle proxy instances use zero network resources.
|
|
336
429
|
// Start MCP server
|
|
337
430
|
const transport = new StdioServerTransport();
|
|
338
431
|
await this.server.connect(transport);
|
|
339
|
-
console.error('QwickBrain Proxy started');
|
|
432
|
+
console.error('QwickBrain Proxy started (lazy mode - connection starts on first tool call)');
|
|
340
433
|
}
|
|
341
434
|
async stop() {
|
|
342
435
|
this.connectionManager.stop();
|
|
436
|
+
// Stop SSE invalidation listener
|
|
437
|
+
if (this.sseInvalidationListener) {
|
|
438
|
+
this.sseInvalidationListener.stop();
|
|
439
|
+
}
|
|
343
440
|
try {
|
|
344
441
|
await this.qwickbrainClient.disconnect();
|
|
345
442
|
}
|