@inkeep/agents-run-api 0.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.
Files changed (149) hide show
  1. package/README.md +117 -0
  2. package/dist/AgentExecutionServer.d.ts +23 -0
  3. package/dist/AgentExecutionServer.d.ts.map +1 -0
  4. package/dist/AgentExecutionServer.js +32 -0
  5. package/dist/__tests__/setup.d.ts +4 -0
  6. package/dist/__tests__/setup.d.ts.map +1 -0
  7. package/dist/__tests__/setup.js +50 -0
  8. package/dist/__tests__/utils/testProject.d.ts +18 -0
  9. package/dist/__tests__/utils/testProject.d.ts.map +1 -0
  10. package/dist/__tests__/utils/testProject.js +26 -0
  11. package/dist/__tests__/utils/testRequest.d.ts +8 -0
  12. package/dist/__tests__/utils/testRequest.d.ts.map +1 -0
  13. package/dist/__tests__/utils/testRequest.js +32 -0
  14. package/dist/__tests__/utils/testTenant.d.ts +64 -0
  15. package/dist/__tests__/utils/testTenant.d.ts.map +1 -0
  16. package/dist/__tests__/utils/testTenant.js +71 -0
  17. package/dist/a2a/client.d.ts +182 -0
  18. package/dist/a2a/client.d.ts.map +1 -0
  19. package/dist/a2a/client.js +645 -0
  20. package/dist/a2a/handlers.d.ts +4 -0
  21. package/dist/a2a/handlers.d.ts.map +1 -0
  22. package/dist/a2a/handlers.js +657 -0
  23. package/dist/a2a/transfer.d.ts +18 -0
  24. package/dist/a2a/transfer.d.ts.map +1 -0
  25. package/dist/a2a/transfer.js +22 -0
  26. package/dist/a2a/types.d.ts +63 -0
  27. package/dist/a2a/types.d.ts.map +1 -0
  28. package/dist/a2a/types.js +1 -0
  29. package/dist/agents/Agent.d.ts +154 -0
  30. package/dist/agents/Agent.d.ts.map +1 -0
  31. package/dist/agents/Agent.js +1105 -0
  32. package/dist/agents/ModelFactory.d.ts +62 -0
  33. package/dist/agents/ModelFactory.d.ts.map +1 -0
  34. package/dist/agents/ModelFactory.js +208 -0
  35. package/dist/agents/SystemPromptBuilder.d.ts +14 -0
  36. package/dist/agents/SystemPromptBuilder.d.ts.map +1 -0
  37. package/dist/agents/SystemPromptBuilder.js +62 -0
  38. package/dist/agents/ToolSessionManager.d.ts +61 -0
  39. package/dist/agents/ToolSessionManager.d.ts.map +1 -0
  40. package/dist/agents/ToolSessionManager.js +143 -0
  41. package/dist/agents/artifactTools.d.ts +30 -0
  42. package/dist/agents/artifactTools.d.ts.map +1 -0
  43. package/dist/agents/artifactTools.js +463 -0
  44. package/dist/agents/generateTaskHandler.d.ts +41 -0
  45. package/dist/agents/generateTaskHandler.d.ts.map +1 -0
  46. package/dist/agents/generateTaskHandler.js +350 -0
  47. package/dist/agents/relationTools.d.ts +33 -0
  48. package/dist/agents/relationTools.d.ts.map +1 -0
  49. package/dist/agents/relationTools.js +245 -0
  50. package/dist/agents/types.d.ts +23 -0
  51. package/dist/agents/types.d.ts.map +1 -0
  52. package/dist/agents/types.js +1 -0
  53. package/dist/agents/versions/V1Config.d.ts +21 -0
  54. package/dist/agents/versions/V1Config.d.ts.map +1 -0
  55. package/dist/agents/versions/V1Config.js +285 -0
  56. package/dist/app.d.ts +4 -0
  57. package/dist/app.d.ts.map +1 -0
  58. package/dist/app.js +194 -0
  59. package/dist/data/agentGraph.d.ts +4 -0
  60. package/dist/data/agentGraph.d.ts.map +1 -0
  61. package/dist/data/agentGraph.js +73 -0
  62. package/dist/data/agents.d.ts +4 -0
  63. package/dist/data/agents.d.ts.map +1 -0
  64. package/dist/data/agents.js +73 -0
  65. package/dist/data/conversations.d.ts +59 -0
  66. package/dist/data/conversations.d.ts.map +1 -0
  67. package/dist/data/conversations.js +216 -0
  68. package/dist/data/db/clean.d.ts +6 -0
  69. package/dist/data/db/clean.d.ts.map +1 -0
  70. package/dist/data/db/clean.js +77 -0
  71. package/dist/data/db/dbClient.d.ts +3 -0
  72. package/dist/data/db/dbClient.d.ts.map +1 -0
  73. package/dist/data/db/dbClient.js +13 -0
  74. package/dist/env.d.ts +43 -0
  75. package/dist/env.d.ts.map +1 -0
  76. package/dist/env.js +63 -0
  77. package/dist/handlers/executionHandler.d.ts +36 -0
  78. package/dist/handlers/executionHandler.d.ts.map +1 -0
  79. package/dist/handlers/executionHandler.js +402 -0
  80. package/dist/index.d.ts +5 -0
  81. package/dist/index.d.ts.map +1 -0
  82. package/dist/index.js +43 -0
  83. package/dist/instrumentation.d.ts +13 -0
  84. package/dist/instrumentation.d.ts.map +1 -0
  85. package/dist/instrumentation.js +66 -0
  86. package/dist/logger.d.ts +4 -0
  87. package/dist/logger.d.ts.map +1 -0
  88. package/dist/logger.js +32 -0
  89. package/dist/middleware/api-key-auth.d.ts +22 -0
  90. package/dist/middleware/api-key-auth.d.ts.map +1 -0
  91. package/dist/middleware/api-key-auth.js +139 -0
  92. package/dist/middleware/index.d.ts +2 -0
  93. package/dist/middleware/index.d.ts.map +1 -0
  94. package/dist/middleware/index.js +1 -0
  95. package/dist/openapi.d.ts +2 -0
  96. package/dist/openapi.d.ts.map +1 -0
  97. package/dist/openapi.js +36 -0
  98. package/dist/routes/agents.d.ts +4 -0
  99. package/dist/routes/agents.d.ts.map +1 -0
  100. package/dist/routes/agents.js +155 -0
  101. package/dist/routes/chat.d.ts +4 -0
  102. package/dist/routes/chat.d.ts.map +1 -0
  103. package/dist/routes/chat.js +308 -0
  104. package/dist/routes/chatDataStream.d.ts +4 -0
  105. package/dist/routes/chatDataStream.d.ts.map +1 -0
  106. package/dist/routes/chatDataStream.js +179 -0
  107. package/dist/routes/mcp.d.ts +4 -0
  108. package/dist/routes/mcp.d.ts.map +1 -0
  109. package/dist/routes/mcp.js +500 -0
  110. package/dist/tracer.d.ts +24 -0
  111. package/dist/tracer.d.ts.map +1 -0
  112. package/dist/tracer.js +97 -0
  113. package/dist/types/chat.d.ts +25 -0
  114. package/dist/types/chat.d.ts.map +1 -0
  115. package/dist/types/chat.js +1 -0
  116. package/dist/types/execution-context.d.ts +14 -0
  117. package/dist/types/execution-context.d.ts.map +1 -0
  118. package/dist/types/execution-context.js +14 -0
  119. package/dist/utils/agent-operations.d.ts +79 -0
  120. package/dist/utils/agent-operations.d.ts.map +1 -0
  121. package/dist/utils/agent-operations.js +67 -0
  122. package/dist/utils/artifact-component-schema.d.ts +29 -0
  123. package/dist/utils/artifact-component-schema.d.ts.map +1 -0
  124. package/dist/utils/artifact-component-schema.js +119 -0
  125. package/dist/utils/artifact-parser.d.ts +71 -0
  126. package/dist/utils/artifact-parser.d.ts.map +1 -0
  127. package/dist/utils/artifact-parser.js +251 -0
  128. package/dist/utils/cleanup.d.ts +19 -0
  129. package/dist/utils/cleanup.d.ts.map +1 -0
  130. package/dist/utils/cleanup.js +66 -0
  131. package/dist/utils/data-component-schema.d.ts +6 -0
  132. package/dist/utils/data-component-schema.d.ts.map +1 -0
  133. package/dist/utils/data-component-schema.js +43 -0
  134. package/dist/utils/graph-session.d.ts +200 -0
  135. package/dist/utils/graph-session.d.ts.map +1 -0
  136. package/dist/utils/graph-session.js +1009 -0
  137. package/dist/utils/incremental-stream-parser.d.ts +57 -0
  138. package/dist/utils/incremental-stream-parser.d.ts.map +1 -0
  139. package/dist/utils/incremental-stream-parser.js +287 -0
  140. package/dist/utils/response-formatter.d.ts +27 -0
  141. package/dist/utils/response-formatter.d.ts.map +1 -0
  142. package/dist/utils/response-formatter.js +160 -0
  143. package/dist/utils/stream-helpers.d.ts +162 -0
  144. package/dist/utils/stream-helpers.d.ts.map +1 -0
  145. package/dist/utils/stream-helpers.js +385 -0
  146. package/dist/utils/stream-registry.d.ts +18 -0
  147. package/dist/utils/stream-registry.d.ts.map +1 -0
  148. package/dist/utils/stream-registry.js +33 -0
  149. package/package.json +88 -0
@@ -0,0 +1,162 @@
1
+ import type { OperationEvent } from './agent-operations.js';
2
+ export interface StreamHelper {
3
+ writeRole(role?: string): Promise<void>;
4
+ writeContent(content: string): Promise<void>;
5
+ streamData(data: any): Promise<void>;
6
+ streamText(text: string, delayMs?: number): Promise<void>;
7
+ writeError(errorMessage: string): Promise<void>;
8
+ complete(): Promise<void>;
9
+ writeData(type: string, data: any): Promise<void>;
10
+ writeOperation(operation: OperationEvent): Promise<void>;
11
+ }
12
+ export interface HonoSSEStream {
13
+ writeSSE(message: {
14
+ data: string;
15
+ event?: string;
16
+ id?: string;
17
+ }): Promise<void>;
18
+ sleep(ms: number): Promise<unknown>;
19
+ }
20
+ export interface ChatCompletionChunk {
21
+ id: string;
22
+ object: string;
23
+ created: number;
24
+ model: string;
25
+ choices: Array<{
26
+ index: number;
27
+ delta: {
28
+ role?: string;
29
+ content?: string;
30
+ };
31
+ finish_reason: string | null;
32
+ }>;
33
+ }
34
+ export declare class SSEStreamHelper implements StreamHelper {
35
+ private stream;
36
+ private requestId;
37
+ private timestamp;
38
+ constructor(stream: HonoSSEStream, requestId: string, timestamp: number);
39
+ private get sessionId();
40
+ /**
41
+ * Write the initial role message
42
+ */
43
+ writeRole(role?: string): Promise<void>;
44
+ /**
45
+ * Write content chunk
46
+ */
47
+ writeContent(content: string): Promise<void>;
48
+ /**
49
+ * Stream text word by word with optional delay
50
+ */
51
+ streamText(text: string, delayMs?: number): Promise<void>;
52
+ streamData(data: any): Promise<void>;
53
+ /**
54
+ * Write error message
55
+ */
56
+ writeError(errorMessage: string): Promise<void>;
57
+ /**
58
+ * Write the final completion message
59
+ */
60
+ writeCompletion(finishReason?: string): Promise<void>;
61
+ /**
62
+ * Write the final [DONE] message
63
+ */
64
+ writeDone(): Promise<void>;
65
+ /**
66
+ * Complete the stream with finish reason and done message
67
+ */
68
+ complete(finishReason?: string): Promise<void>;
69
+ writeData(type: string, data: any): Promise<void>;
70
+ writeOperation(operation: OperationEvent): Promise<void>;
71
+ }
72
+ /**
73
+ * Factory function to create SSE stream helper
74
+ */
75
+ export declare function createSSEStreamHelper(stream: HonoSSEStream, requestId: string, timestamp: number): SSEStreamHelper;
76
+ export interface VercelUIWriter {
77
+ write(chunk: any): void;
78
+ merge(stream: any): void;
79
+ onError?: (error: Error) => void;
80
+ }
81
+ export declare class VercelDataStreamHelper implements StreamHelper {
82
+ private writer;
83
+ private textId;
84
+ private jsonBuffer;
85
+ private sentItems;
86
+ private completedItems;
87
+ private sessionId;
88
+ private static readonly MAX_BUFFER_SIZE;
89
+ private isCompleted;
90
+ constructor(writer: VercelUIWriter);
91
+ setSessionId(sessionId: string): void;
92
+ writeRole(_?: string): Promise<void>;
93
+ writeContent(content: string): Promise<void>;
94
+ streamText(text: string, delayMs?: number): Promise<void>;
95
+ writeData(type: 'operation', data: {
96
+ type: string;
97
+ ctx: any;
98
+ }): Promise<void>;
99
+ writeError(errorMessage: string): Promise<void>;
100
+ streamData(data: any): Promise<void>;
101
+ mergeStream(stream: any): Promise<void>;
102
+ writeCompletion(_finishReason?: string): Promise<void>;
103
+ writeDone(): Promise<void>;
104
+ /**
105
+ * Complete the stream and clean up all memory
106
+ * This is the primary cleanup point to prevent memory leaks between requests
107
+ */
108
+ complete(): Promise<void>;
109
+ /**
110
+ * Clean up all memory allocations
111
+ * Should be called when the stream helper is no longer needed
112
+ */
113
+ cleanup(): void;
114
+ /**
115
+ * Check if the stream has been completed and cleaned up
116
+ */
117
+ isStreamCompleted(): boolean;
118
+ /**
119
+ * Get current memory usage stats (for debugging/monitoring)
120
+ */
121
+ getMemoryStats(): {
122
+ bufferSize: number;
123
+ sentItemsCount: number;
124
+ completedItemsCount: number;
125
+ isCompleted: boolean;
126
+ };
127
+ writeOperation(operation: OperationEvent): Promise<void>;
128
+ }
129
+ export declare function createVercelStreamHelper(writer: VercelUIWriter): VercelDataStreamHelper;
130
+ /**
131
+ * MCP Stream Helper that captures content instead of streaming
132
+ * Used for MCP tool responses which require a single response message
133
+ */
134
+ export declare class MCPStreamHelper implements StreamHelper {
135
+ private capturedText;
136
+ private capturedData;
137
+ private capturedOperations;
138
+ private hasError;
139
+ private errorMessage;
140
+ private sessionId;
141
+ setSessionId(sessionId: string): void;
142
+ writeRole(_role?: string): Promise<void>;
143
+ writeContent(content: string): Promise<void>;
144
+ streamText(text: string, _delayMs?: number): Promise<void>;
145
+ streamData(data: any): Promise<void>;
146
+ writeData(_type: string, data: any): Promise<void>;
147
+ writeError(errorMessage: string): Promise<void>;
148
+ complete(): Promise<void>;
149
+ writeOperation(operation: OperationEvent): Promise<void>;
150
+ /**
151
+ * Get the captured response for MCP tool result
152
+ */
153
+ getCapturedResponse(): {
154
+ text: string;
155
+ data: any[];
156
+ operations: OperationEvent[];
157
+ hasError: boolean;
158
+ errorMessage: string;
159
+ };
160
+ }
161
+ export declare function createMCPStreamHelper(): MCPStreamHelper;
162
+ //# sourceMappingURL=stream-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-helpers.d.ts","sourceRoot":"","sources":["../../src/utils/stream-helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,385 @@
1
+ import { parsePartialJson } from 'ai';
2
+ export class SSEStreamHelper {
3
+ stream;
4
+ requestId;
5
+ timestamp;
6
+ constructor(stream, requestId, timestamp) {
7
+ this.stream = stream;
8
+ this.requestId = requestId;
9
+ this.timestamp = timestamp;
10
+ }
11
+ get sessionId() {
12
+ return this.requestId;
13
+ }
14
+ /**
15
+ * Write the initial role message
16
+ */
17
+ async writeRole(role = 'assistant') {
18
+ await this.stream.writeSSE({
19
+ data: JSON.stringify({
20
+ id: this.requestId,
21
+ object: 'chat.completion.chunk',
22
+ created: this.timestamp,
23
+ choices: [
24
+ {
25
+ index: 0,
26
+ delta: {
27
+ role,
28
+ },
29
+ finish_reason: null,
30
+ },
31
+ ],
32
+ }),
33
+ });
34
+ }
35
+ /**
36
+ * Write content chunk
37
+ */
38
+ async writeContent(content) {
39
+ await this.stream.writeSSE({
40
+ data: JSON.stringify({
41
+ id: this.requestId,
42
+ object: 'chat.completion.chunk',
43
+ created: this.timestamp,
44
+ choices: [
45
+ {
46
+ index: 0,
47
+ delta: {
48
+ content,
49
+ },
50
+ finish_reason: null,
51
+ },
52
+ ],
53
+ }),
54
+ });
55
+ }
56
+ /**
57
+ * Stream text word by word with optional delay
58
+ */
59
+ async streamText(text, delayMs = 100) {
60
+ const words = text.split(' ');
61
+ for (let i = 0; i < words.length; i++) {
62
+ await this.stream.sleep(delayMs);
63
+ const content = i === 0 ? words[i] : ` ${words[i]}`;
64
+ await this.writeContent(content);
65
+ }
66
+ }
67
+ async streamData(data) {
68
+ await this.writeContent(JSON.stringify(data));
69
+ }
70
+ /**
71
+ * Write error message
72
+ */
73
+ async writeError(errorMessage) {
74
+ await this.writeContent(`\n\n${errorMessage}`);
75
+ }
76
+ /**
77
+ * Write the final completion message
78
+ */
79
+ async writeCompletion(finishReason = 'stop') {
80
+ await this.stream.writeSSE({
81
+ data: JSON.stringify({
82
+ id: this.requestId,
83
+ object: 'chat.completion.chunk',
84
+ created: this.timestamp,
85
+ choices: [
86
+ {
87
+ index: 0,
88
+ delta: {},
89
+ finish_reason: finishReason,
90
+ },
91
+ ],
92
+ }),
93
+ });
94
+ }
95
+ /**
96
+ * Write the final [DONE] message
97
+ */
98
+ async writeDone() {
99
+ await this.stream.writeSSE({
100
+ data: '[DONE]',
101
+ });
102
+ }
103
+ /**
104
+ * Complete the stream with finish reason and done message
105
+ */
106
+ async complete(finishReason = 'stop') {
107
+ await this.writeCompletion(finishReason);
108
+ await this.writeDone();
109
+ }
110
+ async writeData(type, data) {
111
+ await this.stream.writeSSE({
112
+ data: JSON.stringify({
113
+ id: this.requestId,
114
+ object: 'chat.completion.chunk',
115
+ created: this.timestamp,
116
+ choices: [
117
+ {
118
+ index: 0,
119
+ delta: {
120
+ content: JSON.stringify({ type, data }),
121
+ },
122
+ finish_reason: null,
123
+ },
124
+ ],
125
+ }),
126
+ });
127
+ }
128
+ async writeOperation(operation) {
129
+ await this.writeData('data-operation', operation);
130
+ }
131
+ }
132
+ /**
133
+ * Factory function to create SSE stream helper
134
+ */
135
+ export function createSSEStreamHelper(stream, requestId, timestamp) {
136
+ return new SSEStreamHelper(stream, requestId, timestamp);
137
+ }
138
+ export class VercelDataStreamHelper {
139
+ writer;
140
+ textId = null;
141
+ jsonBuffer = '';
142
+ sentItems = new Map(); // Track what we've sent for each index
143
+ completedItems = new Set(); // Track completed items
144
+ sessionId = null;
145
+ // Memory management - focused on connection completion cleanup
146
+ static MAX_BUFFER_SIZE = 5 * 1024 * 1024; // 5MB limit (more generous during request)
147
+ isCompleted = false;
148
+ constructor(writer) {
149
+ this.writer = writer;
150
+ }
151
+ setSessionId(sessionId) {
152
+ this.sessionId = sessionId;
153
+ }
154
+ // This mirrors SSEStreamHelper API but outputs using Vercel AI SDK writer
155
+ async writeRole(_ = 'assistant') {
156
+ // noop
157
+ }
158
+ async writeContent(content) {
159
+ if (this.isCompleted) {
160
+ console.warn('Attempted to write content to completed stream');
161
+ return;
162
+ }
163
+ if (!this.textId)
164
+ this.textId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
165
+ // Only prevent catastrophic buffer growth during request
166
+ if (this.jsonBuffer.length + content.length > VercelDataStreamHelper.MAX_BUFFER_SIZE) {
167
+ // Keep more context since we're not cleaning up during request
168
+ const keepSize = Math.floor(VercelDataStreamHelper.MAX_BUFFER_SIZE * 0.8);
169
+ this.jsonBuffer = this.jsonBuffer.slice(-keepSize);
170
+ }
171
+ this.jsonBuffer += content;
172
+ const { value, state } = await parsePartialJson(this.jsonBuffer);
173
+ if (!['repaired-parse', 'successful-parse'].includes(state))
174
+ return;
175
+ if (!Array.isArray(value))
176
+ return;
177
+ for (let i = 0; i < value.length; i++) {
178
+ const { type, ...data } = value[i];
179
+ // TODO: Check for kind data and JSON.stringify
180
+ // Create a content hash to check if this item has changed
181
+ const currentContent = JSON.stringify(data);
182
+ const lastSentContent = this.sentItems.get(i);
183
+ // Only send if content has changed or is new
184
+ if (currentContent !== lastSentContent) {
185
+ const chunk = {
186
+ type: 'data-component',
187
+ id: `${this.textId}-${i}`,
188
+ data: { type, ...data },
189
+ };
190
+ this.writer.write(chunk);
191
+ this.sentItems.set(i, currentContent);
192
+ }
193
+ }
194
+ }
195
+ async streamText(text, delayMs = 100) {
196
+ if (this.isCompleted) {
197
+ console.warn('Attempted to stream text to completed stream');
198
+ return;
199
+ }
200
+ // For plain text, write directly to the stream as text chunks
201
+ if (!this.textId)
202
+ this.textId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
203
+ const words = text.split(' ');
204
+ // ------------------------------
205
+ // New Vercel data-stream v2 format
206
+ // ------------------------------
207
+ // Emit "text-start" once at the beginning, followed by "text-delta" chunks
208
+ // for each word (with preceding space when necessary) and finish with
209
+ // a single "text-end".
210
+ const id = this.textId;
211
+ // Start - notify GraphSession that text streaming is starting
212
+ // Import is at the top of the file, we need to call it here
213
+ if (this.sessionId) {
214
+ const { graphSessionManager } = await import('./graph-session.js');
215
+ graphSessionManager.setTextStreaming(this.sessionId, true);
216
+ }
217
+ this.writer.write({
218
+ type: 'text-start',
219
+ id,
220
+ });
221
+ // Deltas (optionally throttled)
222
+ for (let i = 0; i < words.length; i++) {
223
+ if (delayMs > 0) {
224
+ await new Promise((r) => setTimeout(r, delayMs));
225
+ }
226
+ const delta = i === 0 ? words[i] : ` ${words[i]}`;
227
+ this.writer.write({
228
+ type: 'text-delta',
229
+ id,
230
+ delta,
231
+ });
232
+ }
233
+ // End
234
+ this.writer.write({
235
+ type: 'text-end',
236
+ id,
237
+ });
238
+ // Notify GraphSession that text streaming has finished
239
+ if (this.sessionId) {
240
+ const { graphSessionManager } = await import('./graph-session.js');
241
+ graphSessionManager.setTextStreaming(this.sessionId, false);
242
+ }
243
+ }
244
+ async writeData(type, data) {
245
+ if (this.isCompleted) {
246
+ console.warn('Attempted to write data to completed stream');
247
+ return;
248
+ }
249
+ this.writer.write({
250
+ type: `${type}`,
251
+ data,
252
+ });
253
+ }
254
+ async writeError(errorMessage) {
255
+ if (this.isCompleted) {
256
+ console.warn('Attempted to write error to completed stream');
257
+ return;
258
+ }
259
+ this.writer.write({
260
+ type: 'error',
261
+ errorText: errorMessage,
262
+ });
263
+ }
264
+ async streamData(data) {
265
+ await this.writeContent(JSON.stringify(data));
266
+ }
267
+ async mergeStream(stream) {
268
+ if (this.isCompleted) {
269
+ console.warn('Attempted to merge stream to completed stream');
270
+ return;
271
+ }
272
+ this.writer.merge(stream);
273
+ }
274
+ async writeCompletion(_finishReason = 'stop') {
275
+ // Completion is handled automatically by Vercel's writer
276
+ }
277
+ async writeDone() {
278
+ // Done is handled automatically by Vercel's writer
279
+ }
280
+ /**
281
+ * Complete the stream and clean up all memory
282
+ * This is the primary cleanup point to prevent memory leaks between requests
283
+ */
284
+ async complete() {
285
+ if (this.isCompleted)
286
+ return;
287
+ // Mark as completed to prevent further writes
288
+ this.isCompleted = true;
289
+ // Clean up all buffers and references
290
+ this.cleanup();
291
+ }
292
+ /**
293
+ * Clean up all memory allocations
294
+ * Should be called when the stream helper is no longer needed
295
+ */
296
+ cleanup() {
297
+ this.jsonBuffer = '';
298
+ this.sentItems.clear();
299
+ this.completedItems.clear();
300
+ this.textId = null;
301
+ }
302
+ /**
303
+ * Check if the stream has been completed and cleaned up
304
+ */
305
+ isStreamCompleted() {
306
+ return this.isCompleted;
307
+ }
308
+ /**
309
+ * Get current memory usage stats (for debugging/monitoring)
310
+ */
311
+ getMemoryStats() {
312
+ return {
313
+ bufferSize: this.jsonBuffer.length,
314
+ sentItemsCount: this.sentItems.size,
315
+ completedItemsCount: this.completedItems.size,
316
+ isCompleted: this.isCompleted,
317
+ };
318
+ }
319
+ async writeOperation(operation) {
320
+ this.writer.write({
321
+ id: 'id' in operation ? operation.id : undefined,
322
+ type: 'data-operation',
323
+ data: operation,
324
+ });
325
+ }
326
+ }
327
+ export function createVercelStreamHelper(writer) {
328
+ return new VercelDataStreamHelper(writer);
329
+ }
330
+ /**
331
+ * MCP Stream Helper that captures content instead of streaming
332
+ * Used for MCP tool responses which require a single response message
333
+ */
334
+ export class MCPStreamHelper {
335
+ capturedText = '';
336
+ capturedData = [];
337
+ capturedOperations = [];
338
+ hasError = false;
339
+ errorMessage = '';
340
+ sessionId = null;
341
+ setSessionId(sessionId) {
342
+ this.sessionId = sessionId;
343
+ }
344
+ async writeRole(_role) {
345
+ // No-op for MCP
346
+ }
347
+ async writeContent(content) {
348
+ this.capturedText += content;
349
+ }
350
+ async streamText(text, _delayMs) {
351
+ // Capture text without streaming delay
352
+ this.capturedText += text;
353
+ }
354
+ async streamData(data) {
355
+ this.capturedData.push(data);
356
+ }
357
+ async writeData(_type, data) {
358
+ this.capturedData.push(data);
359
+ }
360
+ async writeError(errorMessage) {
361
+ this.hasError = true;
362
+ this.errorMessage = errorMessage;
363
+ }
364
+ async complete() {
365
+ // No-op for MCP
366
+ }
367
+ async writeOperation(operation) {
368
+ this.capturedOperations.push(operation);
369
+ }
370
+ /**
371
+ * Get the captured response for MCP tool result
372
+ */
373
+ getCapturedResponse() {
374
+ return {
375
+ text: this.capturedText,
376
+ data: this.capturedData,
377
+ operations: this.capturedOperations,
378
+ hasError: this.hasError,
379
+ errorMessage: this.errorMessage,
380
+ };
381
+ }
382
+ }
383
+ export function createMCPStreamHelper() {
384
+ return new MCPStreamHelper();
385
+ }
@@ -0,0 +1,18 @@
1
+ import type { StreamHelper } from './stream-helpers.js';
2
+ /**
3
+ * Register a StreamHelper for a specific request ID
4
+ */
5
+ export declare function registerStreamHelper(requestId: string, streamHelper: StreamHelper): void;
6
+ /**
7
+ * Get a StreamHelper by request ID
8
+ */
9
+ export declare function getStreamHelper(requestId: string): StreamHelper | undefined;
10
+ /**
11
+ * Unregister a StreamHelper for a specific request ID
12
+ */
13
+ export declare function unregisterStreamHelper(requestId: string): void;
14
+ /**
15
+ * Get registry size (for debugging)
16
+ */
17
+ export declare function getRegistrySize(): number;
18
+ //# sourceMappingURL=stream-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-registry.d.ts","sourceRoot":"","sources":["../../src/utils/stream-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAQxD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,GAAG,IAAI,CAOxF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAE3E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAE9D;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Global registry for StreamHelper instances
3
+ * Allows agents to access streamHelper via requestId across A2A boundaries
4
+ */
5
+ const streamHelperRegistry = new Map();
6
+ /**
7
+ * Register a StreamHelper for a specific request ID
8
+ */
9
+ export function registerStreamHelper(requestId, streamHelper) {
10
+ streamHelperRegistry.set(requestId, streamHelper);
11
+ // Set sessionId for stream helpers that support it
12
+ if ('setSessionId' in streamHelper && typeof streamHelper.setSessionId === 'function') {
13
+ streamHelper.setSessionId(requestId);
14
+ }
15
+ }
16
+ /**
17
+ * Get a StreamHelper by request ID
18
+ */
19
+ export function getStreamHelper(requestId) {
20
+ return streamHelperRegistry.get(requestId);
21
+ }
22
+ /**
23
+ * Unregister a StreamHelper for a specific request ID
24
+ */
25
+ export function unregisterStreamHelper(requestId) {
26
+ streamHelperRegistry.delete(requestId);
27
+ }
28
+ /**
29
+ * Get registry size (for debugging)
30
+ */
31
+ export function getRegistrySize() {
32
+ return streamHelperRegistry.size;
33
+ }