opencode-graphiti 0.0.0-development

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 (179) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +358 -0
  3. package/esm/_dnt.polyfills.d.ts +166 -0
  4. package/esm/_dnt.polyfills.d.ts.map +1 -0
  5. package/esm/_dnt.polyfills.js +177 -0
  6. package/esm/_dnt.shims.d.ts +6 -0
  7. package/esm/_dnt.shims.d.ts.map +1 -0
  8. package/esm/_dnt.shims.js +61 -0
  9. package/esm/deno.d.ts +45 -0
  10. package/esm/deno.d.ts.map +1 -0
  11. package/esm/deno.js +39 -0
  12. package/esm/mod.d.ts +3 -0
  13. package/esm/mod.d.ts.map +1 -0
  14. package/esm/mod.js +2 -0
  15. package/esm/package.json +3 -0
  16. package/esm/src/config.d.ts +20 -0
  17. package/esm/src/config.d.ts.map +1 -0
  18. package/esm/src/config.js +246 -0
  19. package/esm/src/handlers/chat.d.ts +14 -0
  20. package/esm/src/handlers/chat.d.ts.map +1 -0
  21. package/esm/src/handlers/chat.js +60 -0
  22. package/esm/src/handlers/compacting.d.ts +9 -0
  23. package/esm/src/handlers/compacting.d.ts.map +1 -0
  24. package/esm/src/handlers/compacting.js +30 -0
  25. package/esm/src/handlers/event.d.ts +22 -0
  26. package/esm/src/handlers/event.d.ts.map +1 -0
  27. package/esm/src/handlers/event.js +287 -0
  28. package/esm/src/handlers/messages.d.ts +9 -0
  29. package/esm/src/handlers/messages.d.ts.map +1 -0
  30. package/esm/src/handlers/messages.js +93 -0
  31. package/esm/src/index.d.ts +5 -0
  32. package/esm/src/index.d.ts.map +1 -0
  33. package/esm/src/index.js +153 -0
  34. package/esm/src/services/batch-drain.d.ts +23 -0
  35. package/esm/src/services/batch-drain.d.ts.map +1 -0
  36. package/esm/src/services/batch-drain.js +217 -0
  37. package/esm/src/services/connection-manager.d.ts +104 -0
  38. package/esm/src/services/connection-manager.d.ts.map +1 -0
  39. package/esm/src/services/connection-manager.js +621 -0
  40. package/esm/src/services/constants.d.ts +7 -0
  41. package/esm/src/services/constants.d.ts.map +1 -0
  42. package/esm/src/services/constants.js +6 -0
  43. package/esm/src/services/context-limit.d.ts +3 -0
  44. package/esm/src/services/context-limit.d.ts.map +1 -0
  45. package/esm/src/services/context-limit.js +44 -0
  46. package/esm/src/services/event-extractor.d.ts +29 -0
  47. package/esm/src/services/event-extractor.d.ts.map +1 -0
  48. package/esm/src/services/event-extractor.js +659 -0
  49. package/esm/src/services/graphiti-async.d.ts +22 -0
  50. package/esm/src/services/graphiti-async.d.ts.map +1 -0
  51. package/esm/src/services/graphiti-async.js +219 -0
  52. package/esm/src/services/graphiti-mcp.d.ts +57 -0
  53. package/esm/src/services/graphiti-mcp.d.ts.map +1 -0
  54. package/esm/src/services/graphiti-mcp.js +194 -0
  55. package/esm/src/services/logger.d.ts +9 -0
  56. package/esm/src/services/logger.d.ts.map +1 -0
  57. package/esm/src/services/logger.js +104 -0
  58. package/esm/src/services/opencode-warning.d.ts +8 -0
  59. package/esm/src/services/opencode-warning.d.ts.map +1 -0
  60. package/esm/src/services/opencode-warning.js +104 -0
  61. package/esm/src/services/redis-cache.d.ts +27 -0
  62. package/esm/src/services/redis-cache.d.ts.map +1 -0
  63. package/esm/src/services/redis-cache.js +215 -0
  64. package/esm/src/services/redis-client.d.ts +89 -0
  65. package/esm/src/services/redis-client.d.ts.map +1 -0
  66. package/esm/src/services/redis-client.js +906 -0
  67. package/esm/src/services/redis-events.d.ts +46 -0
  68. package/esm/src/services/redis-events.d.ts.map +1 -0
  69. package/esm/src/services/redis-events.js +517 -0
  70. package/esm/src/services/redis-snapshot.d.ts +16 -0
  71. package/esm/src/services/redis-snapshot.d.ts.map +1 -0
  72. package/esm/src/services/redis-snapshot.js +184 -0
  73. package/esm/src/services/render-utils.d.ts +23 -0
  74. package/esm/src/services/render-utils.d.ts.map +1 -0
  75. package/esm/src/services/render-utils.js +149 -0
  76. package/esm/src/services/runtime-teardown.d.ts +23 -0
  77. package/esm/src/services/runtime-teardown.d.ts.map +1 -0
  78. package/esm/src/services/runtime-teardown.js +119 -0
  79. package/esm/src/services/sdk-normalize.d.ts +55 -0
  80. package/esm/src/services/sdk-normalize.d.ts.map +1 -0
  81. package/esm/src/services/sdk-normalize.js +61 -0
  82. package/esm/src/session.d.ts +74 -0
  83. package/esm/src/session.d.ts.map +1 -0
  84. package/esm/src/session.js +694 -0
  85. package/esm/src/types/index.d.ts +120 -0
  86. package/esm/src/types/index.d.ts.map +1 -0
  87. package/esm/src/types/index.js +28 -0
  88. package/esm/src/utils.d.ts +27 -0
  89. package/esm/src/utils.d.ts.map +1 -0
  90. package/esm/src/utils.js +76 -0
  91. package/package.json +59 -0
  92. package/script/_dnt.polyfills.d.ts +166 -0
  93. package/script/_dnt.polyfills.d.ts.map +1 -0
  94. package/script/_dnt.polyfills.js +180 -0
  95. package/script/_dnt.shims.d.ts +6 -0
  96. package/script/_dnt.shims.d.ts.map +1 -0
  97. package/script/_dnt.shims.js +65 -0
  98. package/script/deno.d.ts +45 -0
  99. package/script/deno.d.ts.map +1 -0
  100. package/script/deno.js +41 -0
  101. package/script/mod.d.ts +3 -0
  102. package/script/mod.d.ts.map +1 -0
  103. package/script/mod.js +6 -0
  104. package/script/package.json +3 -0
  105. package/script/src/config.d.ts +20 -0
  106. package/script/src/config.d.ts.map +1 -0
  107. package/script/src/config.js +256 -0
  108. package/script/src/handlers/chat.d.ts +14 -0
  109. package/script/src/handlers/chat.d.ts.map +1 -0
  110. package/script/src/handlers/chat.js +63 -0
  111. package/script/src/handlers/compacting.d.ts +9 -0
  112. package/script/src/handlers/compacting.d.ts.map +1 -0
  113. package/script/src/handlers/compacting.js +33 -0
  114. package/script/src/handlers/event.d.ts +22 -0
  115. package/script/src/handlers/event.d.ts.map +1 -0
  116. package/script/src/handlers/event.js +290 -0
  117. package/script/src/handlers/messages.d.ts +9 -0
  118. package/script/src/handlers/messages.d.ts.map +1 -0
  119. package/script/src/handlers/messages.js +96 -0
  120. package/script/src/index.d.ts +5 -0
  121. package/script/src/index.d.ts.map +1 -0
  122. package/script/src/index.js +159 -0
  123. package/script/src/services/batch-drain.d.ts +23 -0
  124. package/script/src/services/batch-drain.d.ts.map +1 -0
  125. package/script/src/services/batch-drain.js +221 -0
  126. package/script/src/services/connection-manager.d.ts +104 -0
  127. package/script/src/services/connection-manager.d.ts.map +1 -0
  128. package/script/src/services/connection-manager.js +635 -0
  129. package/script/src/services/constants.d.ts +7 -0
  130. package/script/src/services/constants.d.ts.map +1 -0
  131. package/script/src/services/constants.js +9 -0
  132. package/script/src/services/context-limit.d.ts +3 -0
  133. package/script/src/services/context-limit.d.ts.map +1 -0
  134. package/script/src/services/context-limit.js +47 -0
  135. package/script/src/services/event-extractor.d.ts +29 -0
  136. package/script/src/services/event-extractor.d.ts.map +1 -0
  137. package/script/src/services/event-extractor.js +669 -0
  138. package/script/src/services/graphiti-async.d.ts +22 -0
  139. package/script/src/services/graphiti-async.d.ts.map +1 -0
  140. package/script/src/services/graphiti-async.js +223 -0
  141. package/script/src/services/graphiti-mcp.d.ts +57 -0
  142. package/script/src/services/graphiti-mcp.d.ts.map +1 -0
  143. package/script/src/services/graphiti-mcp.js +198 -0
  144. package/script/src/services/logger.d.ts +9 -0
  145. package/script/src/services/logger.d.ts.map +1 -0
  146. package/script/src/services/logger.js +142 -0
  147. package/script/src/services/opencode-warning.d.ts +8 -0
  148. package/script/src/services/opencode-warning.d.ts.map +1 -0
  149. package/script/src/services/opencode-warning.js +114 -0
  150. package/script/src/services/redis-cache.d.ts +27 -0
  151. package/script/src/services/redis-cache.d.ts.map +1 -0
  152. package/script/src/services/redis-cache.js +219 -0
  153. package/script/src/services/redis-client.d.ts +89 -0
  154. package/script/src/services/redis-client.d.ts.map +1 -0
  155. package/script/src/services/redis-client.js +943 -0
  156. package/script/src/services/redis-events.d.ts +46 -0
  157. package/script/src/services/redis-events.d.ts.map +1 -0
  158. package/script/src/services/redis-events.js +535 -0
  159. package/script/src/services/redis-snapshot.d.ts +16 -0
  160. package/script/src/services/redis-snapshot.d.ts.map +1 -0
  161. package/script/src/services/redis-snapshot.js +189 -0
  162. package/script/src/services/render-utils.d.ts +23 -0
  163. package/script/src/services/render-utils.d.ts.map +1 -0
  164. package/script/src/services/render-utils.js +165 -0
  165. package/script/src/services/runtime-teardown.d.ts +23 -0
  166. package/script/src/services/runtime-teardown.d.ts.map +1 -0
  167. package/script/src/services/runtime-teardown.js +155 -0
  168. package/script/src/services/sdk-normalize.d.ts +55 -0
  169. package/script/src/services/sdk-normalize.d.ts.map +1 -0
  170. package/script/src/services/sdk-normalize.js +67 -0
  171. package/script/src/session.d.ts +74 -0
  172. package/script/src/session.d.ts.map +1 -0
  173. package/script/src/session.js +698 -0
  174. package/script/src/types/index.d.ts +120 -0
  175. package/script/src/types/index.d.ts.map +1 -0
  176. package/script/src/types/index.js +33 -0
  177. package/script/src/utils.d.ts +27 -0
  178. package/script/src/utils.d.ts.map +1 -0
  179. package/script/src/utils.js +87 -0
@@ -0,0 +1,635 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.GraphitiConnectionManager = exports.GraphitiSessionExpiredError = exports.GraphitiTransportError = exports.GraphitiRequestTimeoutError = exports.GraphitiQueueTimeoutError = exports.GraphitiOfflineError = void 0;
7
+ exports.isGraphitiOfflineError = isGraphitiOfflineError;
8
+ exports.isGraphitiTimeoutError = isGraphitiTimeoutError;
9
+ const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
10
+ const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/client/streamableHttp.js");
11
+ const deno_js_1 = __importDefault(require("../../deno.js"));
12
+ const logger_js_1 = require("./logger.js");
13
+ class GraphitiOfflineError extends Error {
14
+ constructor(state, message) {
15
+ super(message ??
16
+ (state === "closing"
17
+ ? "Graphiti connection manager is closing"
18
+ : state === "stopped"
19
+ ? "Graphiti connection manager is stopped"
20
+ : "Graphiti connection manager is offline"));
21
+ Object.defineProperty(this, "state", {
22
+ enumerable: true,
23
+ configurable: true,
24
+ writable: true,
25
+ value: state
26
+ });
27
+ Object.defineProperty(this, "kind", {
28
+ enumerable: true,
29
+ configurable: true,
30
+ writable: true,
31
+ value: "offline"
32
+ });
33
+ this.name = "GraphitiOfflineError";
34
+ }
35
+ }
36
+ exports.GraphitiOfflineError = GraphitiOfflineError;
37
+ class GraphitiQueueTimeoutError extends Error {
38
+ constructor(message = "Graphiti request timed out while waiting for connection") {
39
+ super(message);
40
+ Object.defineProperty(this, "kind", {
41
+ enumerable: true,
42
+ configurable: true,
43
+ writable: true,
44
+ value: "queue-timeout"
45
+ });
46
+ this.name = "GraphitiQueueTimeoutError";
47
+ }
48
+ }
49
+ exports.GraphitiQueueTimeoutError = GraphitiQueueTimeoutError;
50
+ class GraphitiRequestTimeoutError extends Error {
51
+ constructor(message = "Graphiti request timed out") {
52
+ super(message);
53
+ Object.defineProperty(this, "kind", {
54
+ enumerable: true,
55
+ configurable: true,
56
+ writable: true,
57
+ value: "request-timeout"
58
+ });
59
+ this.name = "GraphitiRequestTimeoutError";
60
+ }
61
+ }
62
+ exports.GraphitiRequestTimeoutError = GraphitiRequestTimeoutError;
63
+ class GraphitiTransportError extends Error {
64
+ constructor(message = "Graphiti transport failure") {
65
+ super(message);
66
+ Object.defineProperty(this, "kind", {
67
+ enumerable: true,
68
+ configurable: true,
69
+ writable: true,
70
+ value: "transport-failure"
71
+ });
72
+ this.name = "GraphitiTransportError";
73
+ }
74
+ }
75
+ exports.GraphitiTransportError = GraphitiTransportError;
76
+ class GraphitiSessionExpiredError extends Error {
77
+ constructor(message = "Graphiti session expired") {
78
+ super(message);
79
+ Object.defineProperty(this, "kind", {
80
+ enumerable: true,
81
+ configurable: true,
82
+ writable: true,
83
+ value: "session-expired"
84
+ });
85
+ this.name = "GraphitiSessionExpiredError";
86
+ }
87
+ }
88
+ exports.GraphitiSessionExpiredError = GraphitiSessionExpiredError;
89
+ function isGraphitiOfflineError(err) {
90
+ return err instanceof GraphitiOfflineError;
91
+ }
92
+ function isGraphitiTimeoutError(err) {
93
+ return err instanceof GraphitiQueueTimeoutError ||
94
+ err instanceof GraphitiRequestTimeoutError;
95
+ }
96
+ const validateEndpoint = (endpoint) => {
97
+ const normalized = endpoint.trim();
98
+ if (!normalized) {
99
+ throw new Error("Graphiti endpoint must not be empty");
100
+ }
101
+ new URL(normalized);
102
+ return normalized;
103
+ };
104
+ function createMcpConnection(endpoint) {
105
+ const client = new index_js_1.Client({
106
+ name: deno_js_1.default.name,
107
+ version: deno_js_1.default.version,
108
+ });
109
+ const transport = new streamableHttp_js_1.StreamableHTTPClientTransport(new URL(endpoint));
110
+ return {
111
+ connect: () => client.connect(transport),
112
+ close: () => client.close(),
113
+ callTool: (request) => client.callTool(request),
114
+ };
115
+ }
116
+ function getErrorMessage(err) {
117
+ if (typeof err === "string")
118
+ return err;
119
+ if (!err || typeof err !== "object")
120
+ return "";
121
+ const { message, cause } = err;
122
+ if (typeof message === "string")
123
+ return message;
124
+ if (cause)
125
+ return getErrorMessage(cause);
126
+ return "";
127
+ }
128
+ function isRequestTimeout(err) {
129
+ if (!err || typeof err !== "object") {
130
+ return typeof err === "string" && /request timed out/i.test(err);
131
+ }
132
+ const { code } = err;
133
+ return code === -32001 || /request timed out/i.test(getErrorMessage(err));
134
+ }
135
+ function isSessionExpired(err) {
136
+ return !!(err &&
137
+ typeof err === "object" &&
138
+ "code" in err &&
139
+ err.code === 404);
140
+ }
141
+ function isTransportFailure(err) {
142
+ if (!err)
143
+ return false;
144
+ if (isRequestTimeout(err) || isSessionExpired(err))
145
+ return false;
146
+ const message = getErrorMessage(err);
147
+ if (/(socket hang up|fetch failed|network|connection reset|connection refused|econnrefused|terminated|broken pipe|stream closed|unexpected end|transport)/i
148
+ .test(message)) {
149
+ return true;
150
+ }
151
+ if (typeof err === "object") {
152
+ const { name } = err;
153
+ return name === "TypeError" && message.length > 0;
154
+ }
155
+ return false;
156
+ }
157
+ class GraphitiConnectionManager {
158
+ constructor(options) {
159
+ Object.defineProperty(this, "endpoint", {
160
+ enumerable: true,
161
+ configurable: true,
162
+ writable: true,
163
+ value: void 0
164
+ });
165
+ Object.defineProperty(this, "requestDeadlineMs", {
166
+ enumerable: true,
167
+ configurable: true,
168
+ writable: true,
169
+ value: void 0
170
+ });
171
+ Object.defineProperty(this, "queueCapacity", {
172
+ enumerable: true,
173
+ configurable: true,
174
+ writable: true,
175
+ value: void 0
176
+ });
177
+ Object.defineProperty(this, "startupTimeoutMs", {
178
+ enumerable: true,
179
+ configurable: true,
180
+ writable: true,
181
+ value: void 0
182
+ });
183
+ Object.defineProperty(this, "reconnectInitialDelayMs", {
184
+ enumerable: true,
185
+ configurable: true,
186
+ writable: true,
187
+ value: void 0
188
+ });
189
+ Object.defineProperty(this, "reconnectMaxDelayMs", {
190
+ enumerable: true,
191
+ configurable: true,
192
+ writable: true,
193
+ value: void 0
194
+ });
195
+ Object.defineProperty(this, "reconnectMultiplier", {
196
+ enumerable: true,
197
+ configurable: true,
198
+ writable: true,
199
+ value: void 0
200
+ });
201
+ Object.defineProperty(this, "reconnectJitter", {
202
+ enumerable: true,
203
+ configurable: true,
204
+ writable: true,
205
+ value: void 0
206
+ });
207
+ Object.defineProperty(this, "connectionFactory", {
208
+ enumerable: true,
209
+ configurable: true,
210
+ writable: true,
211
+ value: void 0
212
+ });
213
+ Object.defineProperty(this, "random", {
214
+ enumerable: true,
215
+ configurable: true,
216
+ writable: true,
217
+ value: void 0
218
+ });
219
+ Object.defineProperty(this, "now", {
220
+ enumerable: true,
221
+ configurable: true,
222
+ writable: true,
223
+ value: void 0
224
+ });
225
+ Object.defineProperty(this, "setTimerImpl", {
226
+ enumerable: true,
227
+ configurable: true,
228
+ writable: true,
229
+ value: void 0
230
+ });
231
+ Object.defineProperty(this, "clearTimerImpl", {
232
+ enumerable: true,
233
+ configurable: true,
234
+ writable: true,
235
+ value: void 0
236
+ });
237
+ Object.defineProperty(this, "state", {
238
+ enumerable: true,
239
+ configurable: true,
240
+ writable: true,
241
+ value: "offline"
242
+ });
243
+ Object.defineProperty(this, "connection", {
244
+ enumerable: true,
245
+ configurable: true,
246
+ writable: true,
247
+ value: null
248
+ });
249
+ Object.defineProperty(this, "connectPromise", {
250
+ enumerable: true,
251
+ configurable: true,
252
+ writable: true,
253
+ value: null
254
+ });
255
+ Object.defineProperty(this, "reconnectTimer", {
256
+ enumerable: true,
257
+ configurable: true,
258
+ writable: true,
259
+ value: null
260
+ });
261
+ Object.defineProperty(this, "pendingRequests", {
262
+ enumerable: true,
263
+ configurable: true,
264
+ writable: true,
265
+ value: []
266
+ });
267
+ Object.defineProperty(this, "readyWaiters", {
268
+ enumerable: true,
269
+ configurable: true,
270
+ writable: true,
271
+ value: new Set()
272
+ });
273
+ Object.defineProperty(this, "reconnectDelayMs", {
274
+ enumerable: true,
275
+ configurable: true,
276
+ writable: true,
277
+ value: void 0
278
+ });
279
+ Object.defineProperty(this, "started", {
280
+ enumerable: true,
281
+ configurable: true,
282
+ writable: true,
283
+ value: false
284
+ });
285
+ Object.defineProperty(this, "flushingQueue", {
286
+ enumerable: true,
287
+ configurable: true,
288
+ writable: true,
289
+ value: false
290
+ });
291
+ Object.defineProperty(this, "stopPromise", {
292
+ enumerable: true,
293
+ configurable: true,
294
+ writable: true,
295
+ value: null
296
+ });
297
+ this.endpoint = validateEndpoint(options.endpoint);
298
+ this.requestDeadlineMs = options.requestDeadlineMs ?? 15_000;
299
+ this.queueCapacity = options.queueCapacity ?? 32;
300
+ this.startupTimeoutMs = options.startupTimeoutMs ?? this.requestDeadlineMs;
301
+ this.reconnectInitialDelayMs = options.reconnectInitialDelayMs ?? 1_000;
302
+ this.reconnectMaxDelayMs = options.reconnectMaxDelayMs ?? 60_000;
303
+ this.reconnectMultiplier = options.reconnectMultiplier ?? 2;
304
+ this.reconnectJitter = options.reconnectJitter ?? 0.25;
305
+ this.connectionFactory = options.connectionFactory ?? createMcpConnection;
306
+ this.random = options.random ?? Math.random;
307
+ this.now = options.now ?? Date.now;
308
+ this.setTimerImpl = options.setTimer ??
309
+ ((callback, delayMs) => setTimeout(callback, delayMs));
310
+ this.clearTimerImpl = options.clearTimer ??
311
+ ((timer) => clearTimeout(timer));
312
+ this.reconnectDelayMs = this.reconnectInitialDelayMs;
313
+ }
314
+ getState() {
315
+ return this.state;
316
+ }
317
+ start() {
318
+ if (this.state === "closing" || this.state === "stopped") {
319
+ throw new GraphitiOfflineError(this.state, this.state === "closing"
320
+ ? "Graphiti connection manager is closing"
321
+ : "Graphiti connection manager has been stopped and cannot be restarted");
322
+ }
323
+ if (this.started)
324
+ return;
325
+ this.started = true;
326
+ void this.reconnect();
327
+ }
328
+ async stop() {
329
+ if (this.state === "stopped")
330
+ return;
331
+ if (this.stopPromise) {
332
+ await this.stopPromise;
333
+ return;
334
+ }
335
+ this.stopPromise = (async () => {
336
+ this.started = false;
337
+ this.state = "closing";
338
+ this.cancelReconnectTimer();
339
+ this.rejectAllPending(new GraphitiOfflineError("stopped", "Graphiti connection manager stopped"));
340
+ this.resolveReadyWaiters(false);
341
+ const connection = this.connection;
342
+ this.connection = null;
343
+ if (connection) {
344
+ try {
345
+ await connection.close();
346
+ }
347
+ catch {
348
+ // Ignore close errors while shutting down.
349
+ }
350
+ }
351
+ this.state = "stopped";
352
+ })();
353
+ await this.stopPromise;
354
+ }
355
+ async ready(timeoutMs = this.startupTimeoutMs) {
356
+ if (this.state === "connected")
357
+ return true;
358
+ if (this.state === "closing" || this.state === "stopped")
359
+ return false;
360
+ return await new Promise((resolve) => {
361
+ let settled = false;
362
+ let timer = null;
363
+ const finish = (value) => {
364
+ if (settled)
365
+ return;
366
+ settled = true;
367
+ if (timer !== null)
368
+ this.clearTimerImpl(timer);
369
+ this.readyWaiters.delete(finish);
370
+ resolve(value);
371
+ };
372
+ this.readyWaiters.add(finish);
373
+ if (timeoutMs >= 0) {
374
+ timer = this.setTimerImpl(() => finish(false), timeoutMs);
375
+ }
376
+ });
377
+ }
378
+ async callTool(name, args, deadlineMs = this.requestDeadlineMs) {
379
+ const sanitizedArgs = Object.fromEntries(Object.entries(args).filter(([_, value]) => value !== null && value !== undefined));
380
+ if (this.state === "closing" || this.state === "stopped") {
381
+ throw new GraphitiOfflineError(this.state);
382
+ }
383
+ if (this.state === "offline") {
384
+ throw new GraphitiOfflineError("offline");
385
+ }
386
+ if (this.state === "connecting") {
387
+ return await this.enqueueRequest(name, sanitizedArgs, deadlineMs);
388
+ }
389
+ return await this.executeConnectedCallWithinDeadline(name, sanitizedArgs, this.now() + deadlineMs);
390
+ }
391
+ async reconnect() {
392
+ if (this.state === "closing" || this.state === "stopped")
393
+ return false;
394
+ if (this.connectPromise)
395
+ return await this.connectPromise;
396
+ this.cancelReconnectTimer();
397
+ this.state = "connecting";
398
+ const attempt = this.performReconnect();
399
+ this.connectPromise = attempt.finally(() => {
400
+ this.connectPromise = null;
401
+ });
402
+ return await this.connectPromise;
403
+ }
404
+ async performReconnect() {
405
+ const previousConnection = this.connection;
406
+ this.connection = null;
407
+ let nextConnection = null;
408
+ if (previousConnection) {
409
+ try {
410
+ await previousConnection.close();
411
+ }
412
+ catch {
413
+ // Ignore stale close failures during reconnect.
414
+ }
415
+ }
416
+ try {
417
+ nextConnection = this.connectionFactory(this.endpoint);
418
+ await nextConnection.connect();
419
+ if (this.state === "closing") {
420
+ try {
421
+ await nextConnection.close();
422
+ }
423
+ catch {
424
+ // Ignore close failures while shutting down.
425
+ }
426
+ return false;
427
+ }
428
+ this.connection = nextConnection;
429
+ this.state = "connected";
430
+ this.reconnectDelayMs = this.reconnectInitialDelayMs;
431
+ this.resolveReadyWaiters(true);
432
+ logger_js_1.logger.info("Connected to Graphiti MCP server at", this.endpoint);
433
+ void this.flushPendingQueue();
434
+ return true;
435
+ }
436
+ catch (err) {
437
+ if (nextConnection) {
438
+ try {
439
+ await nextConnection.close();
440
+ }
441
+ catch {
442
+ // Ignore close failures for failed connects.
443
+ }
444
+ }
445
+ if (this.state !== "closing" && this.state !== "stopped") {
446
+ this.state = "offline";
447
+ this.scheduleReconnect();
448
+ logger_js_1.logger.warn("Failed to connect to Graphiti MCP server", err);
449
+ }
450
+ return false;
451
+ }
452
+ }
453
+ async executeConnectedCall(name, args, deadlineMs) {
454
+ return await this.executeConnectedCallWithinDeadline(name, args, this.now() + deadlineMs);
455
+ }
456
+ async executeConnectedCallWithinDeadline(name, args, deadlineAt, attempt = 0) {
457
+ if (this.state !== "connected" || !this.connection) {
458
+ throw new GraphitiOfflineError("offline");
459
+ }
460
+ const deadlineMs = this.getRemainingDeadlineMs(deadlineAt);
461
+ if (deadlineMs <= 0) {
462
+ throw new GraphitiRequestTimeoutError();
463
+ }
464
+ try {
465
+ return await this.runWithRequestDeadline(this.connection.callTool({ name, arguments: args }), deadlineMs);
466
+ }
467
+ catch (err) {
468
+ if (isRequestTimeout(err)) {
469
+ throw new GraphitiRequestTimeoutError(getErrorMessage(err) || undefined);
470
+ }
471
+ if (isSessionExpired(err)) {
472
+ const typedError = new GraphitiSessionExpiredError(getErrorMessage(err) || undefined);
473
+ if (attempt >= 1) {
474
+ void this.reconnect();
475
+ throw typedError;
476
+ }
477
+ const connected = await this.reconnectWithinDeadline(deadlineAt);
478
+ if (!connected)
479
+ throw typedError;
480
+ return await this.executeConnectedCallWithinDeadline(name, args, deadlineAt, attempt + 1);
481
+ }
482
+ if (isTransportFailure(err)) {
483
+ const typedError = new GraphitiTransportError(getErrorMessage(err) || undefined);
484
+ if (attempt >= 1) {
485
+ void this.reconnect();
486
+ throw typedError;
487
+ }
488
+ const connected = await this.reconnectWithinDeadline(deadlineAt);
489
+ if (!connected)
490
+ throw typedError;
491
+ return await this.executeConnectedCallWithinDeadline(name, args, deadlineAt, attempt + 1);
492
+ }
493
+ throw err;
494
+ }
495
+ }
496
+ getRemainingDeadlineMs(deadlineAt) {
497
+ return deadlineAt - this.now();
498
+ }
499
+ async reconnectWithinDeadline(deadlineAt) {
500
+ const deadlineMs = this.getRemainingDeadlineMs(deadlineAt);
501
+ if (deadlineMs <= 0) {
502
+ throw new GraphitiRequestTimeoutError();
503
+ }
504
+ return await this.runWithRequestDeadline(this.reconnect(), deadlineMs);
505
+ }
506
+ runWithRequestDeadline(task, deadlineMs) {
507
+ return new Promise((resolve, reject) => {
508
+ let settled = false;
509
+ const timer = this.setTimerImpl(() => {
510
+ if (settled)
511
+ return;
512
+ settled = true;
513
+ reject(new GraphitiRequestTimeoutError());
514
+ }, deadlineMs);
515
+ task.then((value) => {
516
+ if (settled)
517
+ return;
518
+ settled = true;
519
+ this.clearTimerImpl(timer);
520
+ resolve(value);
521
+ }, (error) => {
522
+ if (settled)
523
+ return;
524
+ settled = true;
525
+ this.clearTimerImpl(timer);
526
+ reject(error);
527
+ });
528
+ });
529
+ }
530
+ enqueueRequest(name, args, deadlineMs) {
531
+ if (deadlineMs <= 0) {
532
+ return Promise.reject(new GraphitiQueueTimeoutError());
533
+ }
534
+ return new Promise((resolve, reject) => {
535
+ const deadlineAt = this.now() + deadlineMs;
536
+ const pending = {
537
+ name,
538
+ args,
539
+ deadlineAt,
540
+ resolve,
541
+ reject,
542
+ timer: null,
543
+ };
544
+ pending.timer = this.setTimerImpl(() => {
545
+ this.removePendingRequest(pending);
546
+ reject(new GraphitiQueueTimeoutError());
547
+ }, deadlineMs);
548
+ if (this.pendingRequests.length >= this.queueCapacity) {
549
+ const dropped = this.pendingRequests.shift();
550
+ if (dropped) {
551
+ this.clearPendingTimer(dropped);
552
+ dropped.reject(new GraphitiQueueTimeoutError("Graphiti request dropped because the connecting queue is full"));
553
+ }
554
+ }
555
+ this.pendingRequests.push(pending);
556
+ });
557
+ }
558
+ async flushPendingQueue() {
559
+ if (this.flushingQueue || this.state !== "connected")
560
+ return;
561
+ this.flushingQueue = true;
562
+ try {
563
+ while (this.state === "connected" && this.pendingRequests.length > 0) {
564
+ const next = this.pendingRequests.shift();
565
+ if (!next)
566
+ continue;
567
+ this.clearPendingTimer(next);
568
+ if (this.getRemainingDeadlineMs(next.deadlineAt) <= 0) {
569
+ next.reject(new GraphitiQueueTimeoutError());
570
+ continue;
571
+ }
572
+ try {
573
+ const result = await this.executeConnectedCallWithinDeadline(next.name, next.args, next.deadlineAt);
574
+ next.resolve(result);
575
+ }
576
+ catch (err) {
577
+ next.reject(err);
578
+ }
579
+ }
580
+ }
581
+ finally {
582
+ this.flushingQueue = false;
583
+ }
584
+ }
585
+ removePendingRequest(target) {
586
+ const index = this.pendingRequests.indexOf(target);
587
+ if (index >= 0) {
588
+ this.pendingRequests.splice(index, 1);
589
+ }
590
+ this.clearPendingTimer(target);
591
+ }
592
+ clearPendingTimer(request) {
593
+ if (request.timer !== null) {
594
+ this.clearTimerImpl(request.timer);
595
+ request.timer = null;
596
+ }
597
+ }
598
+ rejectAllPending(error) {
599
+ const pending = [...this.pendingRequests];
600
+ this.pendingRequests = [];
601
+ for (const request of pending) {
602
+ this.clearPendingTimer(request);
603
+ request.reject(error);
604
+ }
605
+ }
606
+ scheduleReconnect() {
607
+ if (!this.started || this.state === "closing" || this.state === "stopped" ||
608
+ this.reconnectTimer !== null) {
609
+ return;
610
+ }
611
+ const jitterFactor = 1 + ((this.random() * 2) - 1) * this.reconnectJitter;
612
+ const delayMs = Math.max(0, Math.round(this.reconnectDelayMs * jitterFactor));
613
+ this.reconnectTimer = this.setTimerImpl(() => {
614
+ this.reconnectTimer = null;
615
+ if (this.state === "closing" || this.state === "stopped")
616
+ return;
617
+ void this.reconnect();
618
+ }, delayMs);
619
+ this.reconnectDelayMs = Math.min(this.reconnectMaxDelayMs, Math.max(this.reconnectInitialDelayMs, Math.round(this.reconnectDelayMs * this.reconnectMultiplier)));
620
+ }
621
+ cancelReconnectTimer() {
622
+ if (this.reconnectTimer !== null) {
623
+ this.clearTimerImpl(this.reconnectTimer);
624
+ this.reconnectTimer = null;
625
+ }
626
+ }
627
+ resolveReadyWaiters(value) {
628
+ const waiters = [...this.readyWaiters];
629
+ this.readyWaiters.clear();
630
+ for (const waiter of waiters) {
631
+ waiter(value);
632
+ }
633
+ }
634
+ }
635
+ exports.GraphitiConnectionManager = GraphitiConnectionManager;
@@ -0,0 +1,7 @@
1
+ /** Milliseconds in one day. */
2
+ export declare const DAY_MS: number;
3
+ /** Default token context limit when the provider does not report one. */
4
+ export declare const DEFAULT_CONTEXT_LIMIT = 200000;
5
+ /** Maximum project-scope facts fetched per search query. */
6
+ export declare const PROJECT_MAX_FACTS = 50;
7
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/src/services/constants.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,eAAO,MAAM,MAAM,QAAsB,CAAC;AAE1C,yEAAyE;AACzE,eAAO,MAAM,qBAAqB,SAAU,CAAC;AAE7C,4DAA4D;AAC5D,eAAO,MAAM,iBAAiB,KAAK,CAAC"}
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PROJECT_MAX_FACTS = exports.DEFAULT_CONTEXT_LIMIT = exports.DAY_MS = void 0;
4
+ /** Milliseconds in one day. */
5
+ exports.DAY_MS = 24 * 60 * 60 * 1000;
6
+ /** Default token context limit when the provider does not report one. */
7
+ exports.DEFAULT_CONTEXT_LIMIT = 200_000;
8
+ /** Maximum project-scope facts fetched per search query. */
9
+ exports.PROJECT_MAX_FACTS = 50;
@@ -0,0 +1,3 @@
1
+ import type { OpencodeClient } from "@opencode-ai/sdk";
2
+ export declare function resolveContextLimit(providerID: string, modelID: string, client: OpencodeClient, directory: string | undefined, cache: Map<string, number>): Promise<number>;
3
+ //# sourceMappingURL=context-limit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-limit.d.ts","sourceRoot":"","sources":["../../../src/src/services/context-limit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAkBvD,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACzB,OAAO,CAAC,MAAM,CAAC,CAoCjB"}