opencode-graphiti 0.1.11 → 0.1.12

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 (45) hide show
  1. package/esm/_dnt.polyfills.d.ts +99 -0
  2. package/esm/_dnt.polyfills.d.ts.map +1 -1
  3. package/esm/_dnt.polyfills.js +127 -1
  4. package/esm/_dnt.shims.d.ts +6 -0
  5. package/esm/_dnt.shims.d.ts.map +1 -0
  6. package/esm/_dnt.shims.js +61 -0
  7. package/esm/src/config.d.ts +14 -10
  8. package/esm/src/config.d.ts.map +1 -1
  9. package/esm/src/config.js +103 -43
  10. package/esm/src/index.d.ts.map +1 -1
  11. package/esm/src/index.js +12 -6
  12. package/esm/src/services/client.d.ts +15 -31
  13. package/esm/src/services/client.d.ts.map +1 -1
  14. package/esm/src/services/client.js +77 -139
  15. package/esm/src/services/connection-manager.d.ts +97 -0
  16. package/esm/src/services/connection-manager.d.ts.map +1 -0
  17. package/esm/src/services/connection-manager.js +535 -0
  18. package/esm/src/services/logger.d.ts +2 -0
  19. package/esm/src/services/logger.d.ts.map +1 -1
  20. package/esm/src/services/logger.js +29 -3
  21. package/esm/src/utils.d.ts.map +1 -1
  22. package/esm/src/utils.js +10 -2
  23. package/package.json +2 -2
  24. package/script/_dnt.polyfills.d.ts +99 -0
  25. package/script/_dnt.polyfills.d.ts.map +1 -1
  26. package/script/_dnt.polyfills.js +128 -0
  27. package/script/_dnt.shims.d.ts +6 -0
  28. package/script/_dnt.shims.d.ts.map +1 -0
  29. package/script/_dnt.shims.js +65 -0
  30. package/script/src/config.d.ts +14 -10
  31. package/script/src/config.d.ts.map +1 -1
  32. package/script/src/config.js +106 -76
  33. package/script/src/index.d.ts.map +1 -1
  34. package/script/src/index.js +12 -6
  35. package/script/src/services/client.d.ts +15 -31
  36. package/script/src/services/client.d.ts.map +1 -1
  37. package/script/src/services/client.js +77 -142
  38. package/script/src/services/connection-manager.d.ts +97 -0
  39. package/script/src/services/connection-manager.d.ts.map +1 -0
  40. package/script/src/services/connection-manager.js +549 -0
  41. package/script/src/services/logger.d.ts +2 -0
  42. package/script/src/services/logger.d.ts.map +1 -1
  43. package/script/src/services/logger.js +65 -7
  44. package/script/src/utils.d.ts.map +1 -1
  45. package/script/src/utils.js +10 -2
@@ -1,142 +1,38 @@
1
- import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
- import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
3
- import manifest from "../../deno.js";
1
+ import { GraphitiConnectionManager, GraphitiSessionExpiredError, GraphitiTransportError, isGraphitiOfflineError, isGraphitiTimeoutError, } from "./connection-manager.js";
4
2
  import { logger } from "./logger.js";
5
3
  import { normalizeEpisode } from "./sdk-normalize.js";
6
4
  /**
7
- * Graphiti MCP client wrapper for connecting, querying,
8
- * and persisting episodes with basic reconnection handling.
5
+ * Graphiti domain adapter over the connection manager.
9
6
  */
10
7
  export class GraphitiClient {
11
- /**
12
- * Create a Graphiti client bound to the given MCP endpoint URL.
13
- */
14
- constructor(endpoint) {
15
- Object.defineProperty(this, "client", {
8
+ constructor(endpointOrManager) {
9
+ Object.defineProperty(this, "toolCaller", {
16
10
  enumerable: true,
17
11
  configurable: true,
18
12
  writable: true,
19
13
  value: void 0
20
14
  });
21
- Object.defineProperty(this, "transport", {
22
- enumerable: true,
23
- configurable: true,
24
- writable: true,
25
- value: void 0
26
- });
27
- Object.defineProperty(this, "connected", {
28
- enumerable: true,
29
- configurable: true,
30
- writable: true,
31
- value: false
32
- });
33
- Object.defineProperty(this, "endpoint", {
34
- enumerable: true,
35
- configurable: true,
36
- writable: true,
37
- value: void 0
38
- });
39
- this.endpoint = endpoint;
40
- this.client = new Client({
41
- name: manifest.name,
42
- version: manifest.version,
43
- });
44
- this.transport = new StreamableHTTPClientTransport(new URL(endpoint));
45
- }
46
- /** Create a fresh MCP Client and Transport pair. */
47
- createClientAndTransport() {
48
- this.client = new Client({
49
- name: manifest.name,
50
- version: manifest.version,
51
- });
52
- this.transport = new StreamableHTTPClientTransport(new URL(this.endpoint));
53
- }
54
- /**
55
- * Establish a connection to the Graphiti MCP server.
56
- * Creates a fresh Client/Transport if a previous attempt failed.
57
- */
58
- async connect() {
59
- if (this.connected)
60
- return true;
61
- // If a previous connect() tainted the Client's internal state,
62
- // create fresh instances so the retry starts cleanly.
63
- this.createClientAndTransport();
64
- try {
65
- await this.client.connect(this.transport);
66
- this.connected = true;
67
- logger.info("Connected to Graphiti MCP server at", this.endpoint);
68
- return true;
69
- }
70
- catch (err) {
71
- logger.error("Failed to connect to Graphiti:", err);
72
- return false;
73
- }
74
- }
75
- /**
76
- * Close the underlying MCP client connection.
77
- */
78
- async disconnect() {
79
- if (this.connected) {
80
- await this.client.close();
81
- this.connected = false;
82
- }
83
- }
84
- async callTool(name, args) {
85
- if (!this.connected) {
86
- const ok = await this.connect();
87
- if (!ok)
88
- throw new Error("Not connected to Graphiti");
89
- }
90
- // Sanitize arguments: omit task_id (and others) if null or undefined
91
- const sanitizedArgs = Object.fromEntries(Object.entries(args).filter(([_, v]) => v !== null && v !== undefined));
92
- try {
93
- const result = await this.client.callTool({
94
- name,
95
- arguments: sanitizedArgs,
15
+ if (typeof endpointOrManager === "string") {
16
+ this.toolCaller = new GraphitiConnectionManager({
17
+ endpoint: endpointOrManager,
96
18
  });
97
- return this.parseToolResult(result);
98
19
  }
99
- catch (err) {
100
- if (this.isSessionExpired(err)) {
101
- logger.warn("Graphiti session expired, reconnecting...");
102
- await this.reconnect();
103
- const result = await this.client.callTool({
104
- name,
105
- arguments: sanitizedArgs,
106
- });
107
- return this.parseToolResult(result);
108
- }
109
- throw err;
20
+ else {
21
+ this.toolCaller = endpointOrManager;
110
22
  }
111
23
  }
112
- isSessionExpired(err) {
113
- return !!(err &&
114
- typeof err === "object" &&
115
- "code" in err &&
116
- err.code === 404);
24
+ start() {
25
+ this.toolCaller.start();
117
26
  }
118
- isRequestTimeout(err) {
119
- if (typeof err === "string") {
120
- return /request timed out/i.test(err);
121
- }
122
- if (!err || typeof err !== "object")
123
- return false;
124
- const { code, message } = err;
125
- return code === -32001 ||
126
- (typeof message === "string" && /request timed out/i.test(message));
27
+ async stop() {
28
+ await this.toolCaller.stop();
127
29
  }
128
- async reconnect() {
129
- this.connected = false;
130
- try {
131
- await this.client.close();
132
- }
133
- catch {
134
- // ignore close errors on stale client
135
- }
136
- this.createClientAndTransport();
137
- await this.client.connect(this.transport);
138
- this.connected = true;
139
- logger.info("Reconnected to Graphiti MCP server");
30
+ async connect() {
31
+ this.toolCaller.start();
32
+ return await this.toolCaller.ready();
33
+ }
34
+ async ready(timeoutMs) {
35
+ return await this.toolCaller.ready(timeoutMs);
140
36
  }
141
37
  /**
142
38
  * Parse MCP tool results into JSON when possible.
@@ -165,19 +61,6 @@ export class GraphitiClient {
165
61
  return text;
166
62
  }
167
63
  }
168
- /**
169
- * Add an episode to Graphiti memory.
170
- */
171
- async addEpisode(params) {
172
- await this.callTool("add_memory", {
173
- name: params.name,
174
- episode_body: params.episodeBody,
175
- group_id: params.groupId,
176
- source: params.source || "text",
177
- source_description: params.sourceDescription || "",
178
- });
179
- logger.debug("Added episode:", params.name);
180
- }
181
64
  /**
182
65
  * Extract an array from a tool result that may be a bare array or a
183
66
  * wrapped-array response object (`{ [key]: T[] }`).
@@ -194,6 +77,30 @@ export class GraphitiClient {
194
77
  }
195
78
  return null;
196
79
  }
80
+ /**
81
+ * Add an episode to Graphiti memory.
82
+ */
83
+ async addEpisode(params) {
84
+ try {
85
+ await this.callTool("add_memory", {
86
+ name: params.name,
87
+ episode_body: params.episodeBody,
88
+ group_id: params.groupId,
89
+ source: params.source || "text",
90
+ source_description: params.sourceDescription || "",
91
+ });
92
+ logger.debug("Added episode:", params.name);
93
+ }
94
+ catch (err) {
95
+ if (isGraphitiOfflineError(err) ||
96
+ isGraphitiTimeoutError(err) ||
97
+ err instanceof GraphitiTransportError ||
98
+ err instanceof GraphitiSessionExpiredError) {
99
+ logger.warn("addEpisode failed due to Graphiti availability issue", err);
100
+ }
101
+ throw err;
102
+ }
103
+ }
197
104
  /**
198
105
  * Search Graphiti facts matching the provided query.
199
106
  */
@@ -207,10 +114,19 @@ export class GraphitiClient {
207
114
  return this.parseWrappedArray(result, "facts") ?? [];
208
115
  }
209
116
  catch (err) {
210
- if (this.isRequestTimeout(err)) {
117
+ if (isGraphitiTimeoutError(err)) {
211
118
  logger.warn("searchFacts request timed out; returning no facts");
212
119
  return [];
213
120
  }
121
+ if (isGraphitiOfflineError(err)) {
122
+ logger.warn("searchFacts unavailable; returning no facts");
123
+ return [];
124
+ }
125
+ if (err instanceof GraphitiTransportError ||
126
+ err instanceof GraphitiSessionExpiredError) {
127
+ logger.warn("searchFacts unavailable during reconnect; returning no facts");
128
+ return [];
129
+ }
214
130
  logger.error("searchFacts error:", err);
215
131
  return [];
216
132
  }
@@ -228,10 +144,19 @@ export class GraphitiClient {
228
144
  return this.parseWrappedArray(result, "nodes") ?? [];
229
145
  }
230
146
  catch (err) {
231
- if (this.isRequestTimeout(err)) {
147
+ if (isGraphitiTimeoutError(err)) {
232
148
  logger.warn("searchNodes request timed out; returning no nodes");
233
149
  return [];
234
150
  }
151
+ if (isGraphitiOfflineError(err)) {
152
+ logger.warn("searchNodes unavailable; returning no nodes");
153
+ return [];
154
+ }
155
+ if (err instanceof GraphitiTransportError ||
156
+ err instanceof GraphitiSessionExpiredError) {
157
+ logger.warn("searchNodes unavailable during reconnect; returning no nodes");
158
+ return [];
159
+ }
235
160
  logger.error("searchNodes error:", err);
236
161
  return [];
237
162
  }
@@ -250,10 +175,19 @@ export class GraphitiClient {
250
175
  return raw.map(normalizeEpisode);
251
176
  }
252
177
  catch (err) {
253
- if (this.isRequestTimeout(err)) {
178
+ if (isGraphitiTimeoutError(err)) {
254
179
  logger.warn("getEpisodes request timed out; returning no episodes");
255
180
  return [];
256
181
  }
182
+ if (isGraphitiOfflineError(err)) {
183
+ logger.warn("getEpisodes unavailable; returning no episodes");
184
+ return [];
185
+ }
186
+ if (err instanceof GraphitiTransportError ||
187
+ err instanceof GraphitiSessionExpiredError) {
188
+ logger.warn("getEpisodes unavailable during reconnect; returning no episodes");
189
+ return [];
190
+ }
257
191
  logger.error("getEpisodes error:", err);
258
192
  return [];
259
193
  }
@@ -270,4 +204,8 @@ export class GraphitiClient {
270
204
  return false;
271
205
  }
272
206
  }
207
+ async callTool(name, args) {
208
+ const result = await this.toolCaller.callTool(name, args);
209
+ return this.parseToolResult(result);
210
+ }
273
211
  }
@@ -0,0 +1,97 @@
1
+ export type GraphitiConnectionState = "connecting" | "connected" | "offline" | "closing";
2
+ type TimerHandle = ReturnType<typeof setTimeout> | number;
3
+ export declare class GraphitiOfflineError extends Error {
4
+ readonly state: "offline" | "closing";
5
+ readonly kind = "offline";
6
+ constructor(state: "offline" | "closing", message?: string);
7
+ }
8
+ export declare class GraphitiQueueTimeoutError extends Error {
9
+ readonly kind = "queue-timeout";
10
+ constructor(message?: string);
11
+ }
12
+ export declare class GraphitiRequestTimeoutError extends Error {
13
+ readonly kind = "request-timeout";
14
+ constructor(message?: string);
15
+ }
16
+ export declare class GraphitiTransportError extends Error {
17
+ readonly kind = "transport-failure";
18
+ constructor(message?: string);
19
+ }
20
+ export declare class GraphitiSessionExpiredError extends Error {
21
+ readonly kind = "session-expired";
22
+ constructor(message?: string);
23
+ }
24
+ export declare function isGraphitiOfflineError(err: unknown): err is GraphitiOfflineError;
25
+ export declare function isGraphitiTimeoutError(err: unknown): err is GraphitiQueueTimeoutError | GraphitiRequestTimeoutError;
26
+ export type GraphitiToolRequest = {
27
+ name: string;
28
+ arguments?: Record<string, unknown>;
29
+ };
30
+ export interface GraphitiConnection {
31
+ connect(): Promise<void>;
32
+ close(): Promise<void>;
33
+ callTool(request: GraphitiToolRequest): Promise<unknown>;
34
+ }
35
+ export interface GraphitiToolCaller {
36
+ start(): void;
37
+ stop(): Promise<void>;
38
+ ready(timeoutMs?: number): Promise<boolean>;
39
+ callTool(name: string, args: Record<string, unknown>, deadlineMs?: number): Promise<unknown>;
40
+ }
41
+ type ConnectionFactory = (endpoint: string) => GraphitiConnection;
42
+ type GraphitiConnectionManagerOptions = {
43
+ endpoint: string;
44
+ requestDeadlineMs?: number;
45
+ queueCapacity?: number;
46
+ startupTimeoutMs?: number;
47
+ reconnectInitialDelayMs?: number;
48
+ reconnectMaxDelayMs?: number;
49
+ reconnectMultiplier?: number;
50
+ reconnectJitter?: number;
51
+ connectionFactory?: ConnectionFactory;
52
+ random?: () => number;
53
+ setTimer?: (callback: () => void, delayMs: number) => TimerHandle;
54
+ clearTimer?: (timer: TimerHandle) => void;
55
+ };
56
+ export declare class GraphitiConnectionManager implements GraphitiToolCaller {
57
+ private readonly endpoint;
58
+ private readonly requestDeadlineMs;
59
+ private readonly queueCapacity;
60
+ private readonly startupTimeoutMs;
61
+ private readonly reconnectInitialDelayMs;
62
+ private readonly reconnectMaxDelayMs;
63
+ private readonly reconnectMultiplier;
64
+ private readonly reconnectJitter;
65
+ private readonly connectionFactory;
66
+ private readonly random;
67
+ private readonly setTimerImpl;
68
+ private readonly clearTimerImpl;
69
+ private state;
70
+ private connection;
71
+ private connectPromise;
72
+ private reconnectTimer;
73
+ private pendingRequests;
74
+ private readyWaiters;
75
+ private reconnectDelayMs;
76
+ private started;
77
+ private flushingQueue;
78
+ constructor(options: GraphitiConnectionManagerOptions);
79
+ getState(): GraphitiConnectionState;
80
+ start(): void;
81
+ stop(): Promise<void>;
82
+ ready(timeoutMs?: number): Promise<boolean>;
83
+ callTool(name: string, args: Record<string, unknown>, deadlineMs?: number): Promise<unknown>;
84
+ reconnect(): Promise<boolean>;
85
+ private performReconnect;
86
+ private executeConnectedCall;
87
+ private enqueueRequest;
88
+ private flushPendingQueue;
89
+ private removePendingRequest;
90
+ private clearPendingTimer;
91
+ private rejectAllPending;
92
+ private scheduleReconnect;
93
+ private cancelReconnectTimer;
94
+ private resolveReadyWaiters;
95
+ }
96
+ export {};
97
+ //# sourceMappingURL=connection-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-manager.d.ts","sourceRoot":"","sources":["../../../src/src/services/connection-manager.ts"],"names":[],"mappings":"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"}