@sudocode-ai/local-server 0.1.0 → 0.1.2

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 (117) hide show
  1. package/dist/cli.js +6 -104
  2. package/dist/cli.js.map +1 -7
  3. package/dist/execution/engine/engine.js +10 -0
  4. package/dist/execution/engine/engine.js.map +1 -0
  5. package/dist/execution/engine/simple-engine.js +611 -0
  6. package/dist/execution/engine/simple-engine.js.map +1 -0
  7. package/dist/execution/engine/types.js +10 -0
  8. package/dist/execution/engine/types.js.map +1 -0
  9. package/dist/execution/output/ag-ui-adapter.js +438 -0
  10. package/dist/execution/output/ag-ui-adapter.js.map +1 -0
  11. package/dist/execution/output/ag-ui-integration.js +96 -0
  12. package/dist/execution/output/ag-ui-integration.js.map +1 -0
  13. package/dist/execution/output/claude-code-output-processor.js +769 -0
  14. package/dist/execution/output/claude-code-output-processor.js.map +1 -0
  15. package/dist/execution/output/index.js +15 -0
  16. package/dist/execution/output/index.js.map +1 -0
  17. package/dist/execution/output/types.js +22 -0
  18. package/dist/execution/output/types.js.map +1 -0
  19. package/dist/execution/process/builders/claude.js +59 -0
  20. package/dist/execution/process/builders/claude.js.map +1 -0
  21. package/dist/execution/process/index.js +15 -0
  22. package/dist/execution/process/index.js.map +1 -0
  23. package/dist/execution/process/manager.js +10 -0
  24. package/dist/execution/process/manager.js.map +1 -0
  25. package/dist/execution/process/simple-manager.js +336 -0
  26. package/dist/execution/process/simple-manager.js.map +1 -0
  27. package/dist/execution/process/types.js +10 -0
  28. package/dist/execution/process/types.js.map +1 -0
  29. package/dist/execution/process/utils.js +97 -0
  30. package/dist/execution/process/utils.js.map +1 -0
  31. package/dist/execution/resilience/circuit-breaker.js +291 -0
  32. package/dist/execution/resilience/circuit-breaker.js.map +1 -0
  33. package/dist/execution/resilience/executor.js +10 -0
  34. package/dist/execution/resilience/executor.js.map +1 -0
  35. package/dist/execution/resilience/index.js +15 -0
  36. package/dist/execution/resilience/index.js.map +1 -0
  37. package/dist/execution/resilience/resilient-executor.js +261 -0
  38. package/dist/execution/resilience/resilient-executor.js.map +1 -0
  39. package/dist/execution/resilience/retry.js +234 -0
  40. package/dist/execution/resilience/retry.js.map +1 -0
  41. package/dist/execution/resilience/types.js +30 -0
  42. package/dist/execution/resilience/types.js.map +1 -0
  43. package/dist/execution/transport/event-buffer.js +208 -0
  44. package/dist/execution/transport/event-buffer.js.map +1 -0
  45. package/dist/execution/transport/index.js +10 -0
  46. package/dist/execution/transport/index.js.map +1 -0
  47. package/dist/execution/transport/sse-transport.js +282 -0
  48. package/dist/execution/transport/sse-transport.js.map +1 -0
  49. package/dist/execution/transport/transport-manager.js +231 -0
  50. package/dist/execution/transport/transport-manager.js.map +1 -0
  51. package/dist/execution/workflow/index.js +13 -0
  52. package/dist/execution/workflow/index.js.map +1 -0
  53. package/dist/execution/workflow/linear-orchestrator.js +683 -0
  54. package/dist/execution/workflow/linear-orchestrator.js.map +1 -0
  55. package/dist/execution/workflow/memory-storage.js +68 -0
  56. package/dist/execution/workflow/memory-storage.js.map +1 -0
  57. package/dist/execution/workflow/orchestrator.js +9 -0
  58. package/dist/execution/workflow/orchestrator.js.map +1 -0
  59. package/dist/execution/workflow/types.js +9 -0
  60. package/dist/execution/workflow/types.js.map +1 -0
  61. package/dist/execution/workflow/utils.js +152 -0
  62. package/dist/execution/workflow/utils.js.map +1 -0
  63. package/dist/execution/worktree/config.js +280 -0
  64. package/dist/execution/worktree/config.js.map +1 -0
  65. package/dist/execution/worktree/git-cli.js +189 -0
  66. package/dist/execution/worktree/git-cli.js.map +1 -0
  67. package/dist/execution/worktree/index.js +15 -0
  68. package/dist/execution/worktree/index.js.map +1 -0
  69. package/dist/execution/worktree/manager.js +452 -0
  70. package/dist/execution/worktree/manager.js.map +1 -0
  71. package/dist/execution/worktree/types.js +42 -0
  72. package/dist/execution/worktree/types.js.map +1 -0
  73. package/dist/index.d.ts.map +1 -1
  74. package/dist/index.js +357 -104
  75. package/dist/index.js.map +1 -7
  76. package/dist/routes/executions-stream.js +55 -0
  77. package/dist/routes/executions-stream.js.map +1 -0
  78. package/dist/routes/executions.js +267 -0
  79. package/dist/routes/executions.js.map +1 -0
  80. package/dist/routes/feedback.js +329 -0
  81. package/dist/routes/feedback.js.map +1 -0
  82. package/dist/routes/issues.js +280 -0
  83. package/dist/routes/issues.js.map +1 -0
  84. package/dist/routes/relationships.js +308 -0
  85. package/dist/routes/relationships.js.map +1 -0
  86. package/dist/routes/specs.js +270 -0
  87. package/dist/routes/specs.js.map +1 -0
  88. package/dist/services/db.js +85 -0
  89. package/dist/services/db.js.map +1 -0
  90. package/dist/services/execution-lifecycle.d.ts.map +1 -1
  91. package/dist/services/execution-lifecycle.js +291 -0
  92. package/dist/services/execution-lifecycle.js.map +1 -0
  93. package/dist/services/execution-service.js +676 -0
  94. package/dist/services/execution-service.js.map +1 -0
  95. package/dist/services/executions.js +164 -0
  96. package/dist/services/executions.js.map +1 -0
  97. package/dist/services/export.js +106 -0
  98. package/dist/services/export.js.map +1 -0
  99. package/dist/services/feedback.js +54 -0
  100. package/dist/services/feedback.js.map +1 -0
  101. package/dist/services/issues.js +35 -0
  102. package/dist/services/issues.js.map +1 -0
  103. package/dist/services/prompt-template-engine.js +212 -0
  104. package/dist/services/prompt-template-engine.js.map +1 -0
  105. package/dist/services/prompt-templates.js +236 -0
  106. package/dist/services/prompt-templates.js.map +1 -0
  107. package/dist/services/relationships.js +42 -0
  108. package/dist/services/relationships.js.map +1 -0
  109. package/dist/services/specs.js +35 -0
  110. package/dist/services/specs.js.map +1 -0
  111. package/dist/services/watcher.js +69 -0
  112. package/dist/services/watcher.js.map +1 -0
  113. package/dist/services/websocket.js +389 -0
  114. package/dist/services/websocket.js.map +1 -0
  115. package/dist/utils/sudocode-dir.js +9 -0
  116. package/dist/utils/sudocode-dir.js.map +1 -0
  117. package/package.json +4 -6
@@ -0,0 +1,438 @@
1
+ /**
2
+ * AG-UI Event Adapter
3
+ *
4
+ * Transforms SPEC-007 output processing events into AG-UI protocol events.
5
+ * This adapter subscribes to events from IOutputProcessor and emits standardized
6
+ * AG-UI events that can be consumed by frontends via SSE or WebSocket transports.
7
+ *
8
+ * @module execution/output/ag-ui-adapter
9
+ */
10
+ import { EventType, } from "@ag-ui/core";
11
+ /**
12
+ * AgUiEventAdapter - Transforms SPEC-007 events to AG-UI events
13
+ *
14
+ * This adapter bridges the gap between the Output Processing Layer (SPEC-007)
15
+ * and the AG-UI protocol (SPEC-009). It subscribes to output processor events
16
+ * and emits corresponding AG-UI protocol events.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const adapter = new AgUiEventAdapter('run-123');
21
+ * adapter.onEvent((event) => {
22
+ * console.log('AG-UI event:', event);
23
+ * // Send to SSE transport or WebSocket
24
+ * });
25
+ *
26
+ * const processor = new ClaudeCodeOutputProcessor();
27
+ * adapter.connectToProcessor(processor);
28
+ * adapter.emitRunStarted({ model: 'claude-sonnet-4' });
29
+ * ```
30
+ */
31
+ export class AgUiEventAdapter {
32
+ runId;
33
+ threadId;
34
+ listeners = new Set();
35
+ processor = null;
36
+ currentState = {};
37
+ activeToolCalls = new Map();
38
+ messageCounter = 0;
39
+ /**
40
+ * Create a new AG-UI event adapter
41
+ *
42
+ * @param runId - Unique identifier for this execution run
43
+ * @param threadId - Thread identifier (defaults to runId if not provided)
44
+ */
45
+ constructor(runId, threadId) {
46
+ this.runId = runId;
47
+ this.threadId = threadId || runId;
48
+ }
49
+ /**
50
+ * Connect to an output processor and subscribe to its events
51
+ *
52
+ * @param processor - The output processor to subscribe to
53
+ */
54
+ connectToProcessor(processor) {
55
+ this.processor = processor;
56
+ // Subscribe to all SPEC-007 events
57
+ processor.onToolCall(this.handleToolCall.bind(this));
58
+ processor.onFileChange(this.handleFileChange.bind(this));
59
+ processor.onProgress(this.handleProgress.bind(this));
60
+ processor.onError(this.handleError.bind(this));
61
+ processor.onMessage(this.handleMessage.bind(this));
62
+ processor.onUsage(this.handleUsage.bind(this));
63
+ }
64
+ /**
65
+ * Register an event listener
66
+ *
67
+ * @param listener - Callback to invoke when AG-UI events are emitted
68
+ */
69
+ onEvent(listener) {
70
+ this.listeners.add(listener);
71
+ }
72
+ /**
73
+ * Remove an event listener
74
+ *
75
+ * @param listener - Callback to remove
76
+ */
77
+ offEvent(listener) {
78
+ this.listeners.delete(listener);
79
+ }
80
+ /**
81
+ * Emit RUN_STARTED event
82
+ *
83
+ * @param metadata - Optional run metadata (model, config, etc.)
84
+ */
85
+ emitRunStarted(metadata) {
86
+ const event = {
87
+ type: EventType.RUN_STARTED,
88
+ threadId: this.threadId,
89
+ runId: this.runId,
90
+ timestamp: Date.now(),
91
+ ...(metadata && { rawEvent: metadata }),
92
+ };
93
+ this.emit(event);
94
+ this.emitStateSnapshot();
95
+ }
96
+ /**
97
+ * Emit RUN_FINISHED event
98
+ *
99
+ * @param result - Optional result data
100
+ */
101
+ emitRunFinished(result) {
102
+ const event = {
103
+ type: EventType.RUN_FINISHED,
104
+ threadId: this.threadId,
105
+ runId: this.runId,
106
+ timestamp: Date.now(),
107
+ ...(result && { result }),
108
+ };
109
+ this.emit(event);
110
+ }
111
+ /**
112
+ * Emit a state snapshot with current execution state
113
+ */
114
+ emitStateSnapshot() {
115
+ const metrics = this.processor?.getMetrics();
116
+ const event = {
117
+ type: EventType.STATE_SNAPSHOT,
118
+ timestamp: Date.now(),
119
+ snapshot: {
120
+ ...this.currentState,
121
+ ...(metrics && {
122
+ totalMessages: metrics.totalMessages,
123
+ toolCallCount: metrics.toolCalls.length,
124
+ fileChangeCount: metrics.fileChanges.length,
125
+ errorCount: metrics.errors.length,
126
+ usage: {
127
+ inputTokens: metrics.usage.inputTokens,
128
+ outputTokens: metrics.usage.outputTokens,
129
+ totalTokens: metrics.usage.totalTokens,
130
+ },
131
+ }),
132
+ },
133
+ };
134
+ this.emit(event);
135
+ }
136
+ /**
137
+ * Handle tool call events from SPEC-007
138
+ *
139
+ * Transforms a single ToolCall into a sequence of AG-UI events:
140
+ * - TOOL_CALL_START (when tool is invoked)
141
+ * - TOOL_CALL_ARGS (with input parameters)
142
+ * - TOOL_CALL_END (when tool completes)
143
+ * - TOOL_CALL_RESULT (with result/error)
144
+ */
145
+ handleToolCall = (toolCall) => {
146
+ const toolCallId = toolCall.id;
147
+ const timestamp = Date.now();
148
+ // Check if this is a new tool call or an update to existing one
149
+ if (!this.activeToolCalls.has(toolCallId)) {
150
+ // New tool call - emit START and ARGS
151
+ const messageId = `msg-${this.messageCounter++}`;
152
+ this.activeToolCalls.set(toolCallId, {
153
+ startTime: Date.now(),
154
+ messageId,
155
+ });
156
+ const startEvent = {
157
+ type: EventType.TOOL_CALL_START,
158
+ timestamp,
159
+ toolCallId,
160
+ toolCallName: toolCall.name,
161
+ };
162
+ this.emit(startEvent);
163
+ const argsEvent = {
164
+ type: EventType.TOOL_CALL_ARGS,
165
+ timestamp,
166
+ toolCallId,
167
+ delta: JSON.stringify(toolCall.input),
168
+ };
169
+ this.emit(argsEvent);
170
+ }
171
+ // If tool call is complete (success or error), emit END and RESULT
172
+ if (toolCall.status === "success" || toolCall.status === "error") {
173
+ const toolInfo = this.activeToolCalls.get(toolCallId);
174
+ const duration = toolInfo ? Date.now() - toolInfo.startTime : undefined;
175
+ const endEvent = {
176
+ type: EventType.TOOL_CALL_END,
177
+ timestamp,
178
+ toolCallId,
179
+ ...(duration !== undefined && { rawEvent: { duration } }),
180
+ };
181
+ this.emit(endEvent);
182
+ if (toolInfo) {
183
+ const resultEvent = {
184
+ type: EventType.TOOL_CALL_RESULT,
185
+ timestamp,
186
+ messageId: toolInfo.messageId,
187
+ toolCallId,
188
+ content: toolCall.status === "success"
189
+ ? typeof toolCall.result === "string"
190
+ ? toolCall.result
191
+ : JSON.stringify(toolCall.result)
192
+ : toolCall.error || "Tool call failed",
193
+ };
194
+ this.emit(resultEvent);
195
+ }
196
+ this.activeToolCalls.delete(toolCallId);
197
+ // Emit state delta with updated tool call count
198
+ this.emitStateDelta({
199
+ toolCallCount: this.processor?.getToolCalls().length || 0,
200
+ });
201
+ }
202
+ };
203
+ /**
204
+ * Handle file change events from SPEC-007
205
+ *
206
+ * Transforms FileChange into a CUSTOM event with file operation details
207
+ */
208
+ handleFileChange = (fileChange) => {
209
+ const event = {
210
+ type: EventType.CUSTOM,
211
+ timestamp: Date.now(),
212
+ name: "file_change",
213
+ value: {
214
+ path: fileChange.path,
215
+ operation: fileChange.operation,
216
+ toolCallId: fileChange.toolCallId,
217
+ changes: fileChange.changes,
218
+ },
219
+ };
220
+ this.emit(event);
221
+ // Emit state delta with updated file change count
222
+ this.emitStateDelta({
223
+ fileChangeCount: this.processor?.getFileChanges().length || 0,
224
+ });
225
+ };
226
+ /**
227
+ * Handle progress updates from SPEC-007
228
+ *
229
+ * Transforms ProcessingMetrics into STATE_DELTA events
230
+ */
231
+ handleProgress = (metrics) => {
232
+ this.emitStateDelta({
233
+ totalMessages: metrics.totalMessages,
234
+ toolCallCount: metrics.toolCalls.length,
235
+ fileChangeCount: metrics.fileChanges.length,
236
+ errorCount: metrics.errors.length,
237
+ usage: {
238
+ inputTokens: metrics.usage.inputTokens,
239
+ outputTokens: metrics.usage.outputTokens,
240
+ totalTokens: metrics.usage.totalTokens,
241
+ },
242
+ });
243
+ };
244
+ /**
245
+ * Handle error events from SPEC-007
246
+ *
247
+ * Transforms errors into RUN_ERROR events
248
+ */
249
+ handleError = (error) => {
250
+ const event = {
251
+ type: EventType.RUN_ERROR,
252
+ timestamp: error.timestamp.getTime(),
253
+ message: error.message,
254
+ ...(error.details && { rawEvent: { details: error.details } }),
255
+ };
256
+ this.emit(event);
257
+ // Emit state delta with updated error count
258
+ this.emitStateDelta({
259
+ errorCount: this.processor?.getMetrics().errors.length || 0,
260
+ });
261
+ };
262
+ /**
263
+ * Handle message events
264
+ *
265
+ * Transforms text messages into TEXT_MESSAGE_* AG-UI events.
266
+ * For now, we emit the full message content in a single event.
267
+ */
268
+ handleMessage = (message) => {
269
+ if (message.type !== "text")
270
+ return;
271
+ const messageId = `msg-${this.messageCounter++}`;
272
+ const timestamp = Date.now();
273
+ // Emit TEXT_MESSAGE_START
274
+ const startEvent = {
275
+ type: EventType.TEXT_MESSAGE_START,
276
+ timestamp,
277
+ messageId,
278
+ role: "assistant",
279
+ };
280
+ this.emit(startEvent);
281
+ // Emit TEXT_MESSAGE_CONTENT with the full message
282
+ const contentEvent = {
283
+ type: EventType.TEXT_MESSAGE_CONTENT,
284
+ timestamp,
285
+ messageId,
286
+ delta: message.content,
287
+ };
288
+ this.emit(contentEvent);
289
+ // Emit TEXT_MESSAGE_END
290
+ const endEvent = {
291
+ type: EventType.TEXT_MESSAGE_END,
292
+ timestamp,
293
+ messageId,
294
+ };
295
+ this.emit(endEvent);
296
+ };
297
+ /**
298
+ * Handle usage metric updates
299
+ *
300
+ * Transforms usage metrics into CUSTOM usage events and updates state.
301
+ */
302
+ handleUsage = (usage) => {
303
+ const timestamp = Date.now();
304
+ // Emit USAGE event as CUSTOM event
305
+ const usageEvent = {
306
+ type: EventType.CUSTOM,
307
+ timestamp,
308
+ name: "USAGE_UPDATE",
309
+ value: {
310
+ inputTokens: usage.inputTokens,
311
+ outputTokens: usage.outputTokens,
312
+ cacheTokens: usage.cacheTokens,
313
+ totalTokens: usage.totalTokens,
314
+ cost: usage.cost,
315
+ provider: usage.provider,
316
+ model: usage.model,
317
+ },
318
+ };
319
+ this.emit(usageEvent);
320
+ // Update state with latest usage
321
+ this.emitStateDelta({
322
+ usage: {
323
+ inputTokens: usage.inputTokens,
324
+ outputTokens: usage.outputTokens,
325
+ totalTokens: usage.totalTokens,
326
+ },
327
+ });
328
+ };
329
+ /**
330
+ * Emit a state delta with partial state updates
331
+ *
332
+ * @param updates - Partial state updates to apply
333
+ */
334
+ emitStateDelta(updates) {
335
+ // Update current state
336
+ this.currentState = { ...this.currentState, ...updates };
337
+ // Convert updates to JSON Patch operations
338
+ const delta = Object.entries(updates).map(([key, value]) => ({
339
+ op: "replace",
340
+ path: `/${key}`,
341
+ value,
342
+ }));
343
+ const event = {
344
+ type: EventType.STATE_DELTA,
345
+ timestamp: Date.now(),
346
+ delta,
347
+ };
348
+ this.emit(event);
349
+ }
350
+ /**
351
+ * Emit an AG-UI event to all registered listeners
352
+ *
353
+ * @param event - The event to emit
354
+ */
355
+ emit(event) {
356
+ this.listeners.forEach((listener) => {
357
+ try {
358
+ listener(event);
359
+ }
360
+ catch (error) {
361
+ console.error("Error in AG-UI event listener:", error);
362
+ }
363
+ });
364
+ }
365
+ /**
366
+ * Emit STEP_STARTED event for workflow step execution
367
+ *
368
+ * @param stepId - Unique identifier for the step (stored in rawEvent)
369
+ * @param stepName - Human-readable name of the step
370
+ */
371
+ emitStepStarted(stepId, stepName) {
372
+ const event = {
373
+ type: EventType.STEP_STARTED,
374
+ timestamp: Date.now(),
375
+ stepName,
376
+ rawEvent: {
377
+ runId: this.runId,
378
+ stepId,
379
+ },
380
+ };
381
+ this.emit(event);
382
+ }
383
+ /**
384
+ * Emit STEP_FINISHED event for workflow step completion
385
+ *
386
+ * @param stepId - Unique identifier for the step (stored in rawEvent)
387
+ * @param status - Status of the step ('success' or 'error', stored in rawEvent)
388
+ * @param output - Optional output data from the step (stored in rawEvent)
389
+ */
390
+ emitStepFinished(stepId, status, output) {
391
+ const event = {
392
+ type: EventType.STEP_FINISHED,
393
+ timestamp: Date.now(),
394
+ stepName: stepId, // Use stepId as stepName for now
395
+ rawEvent: {
396
+ runId: this.runId,
397
+ stepId,
398
+ status,
399
+ ...(output && { output }),
400
+ },
401
+ };
402
+ this.emit(event);
403
+ }
404
+ /**
405
+ * Emit RUN_ERROR event when workflow execution fails
406
+ *
407
+ * @param message - Error message
408
+ * @param stack - Optional error stack trace
409
+ * @param code - Optional error code
410
+ */
411
+ emitRunError(message, stack, code) {
412
+ const event = {
413
+ type: EventType.RUN_ERROR,
414
+ timestamp: Date.now(),
415
+ message,
416
+ ...(code && { code }),
417
+ ...(stack && { rawEvent: { stack } }),
418
+ };
419
+ this.emit(event);
420
+ }
421
+ /**
422
+ * Get current adapter state
423
+ *
424
+ * @returns Current state object
425
+ */
426
+ getState() {
427
+ return { ...this.currentState };
428
+ }
429
+ /**
430
+ * Get the run ID
431
+ *
432
+ * @returns The run ID this adapter is tracking
433
+ */
434
+ getRunId() {
435
+ return this.runId;
436
+ }
437
+ }
438
+ //# sourceMappingURL=ag-ui-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ag-ui-adapter.js","sourceRoot":"","sources":["../../../src/execution/output/ag-ui-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * AG-UI Integration Helpers
3
+ *
4
+ * Factory functions and helpers to wire SPEC-007 output processing with SPEC-009 AG-UI streaming.
5
+ * Simplifies the integration between ClaudeCodeOutputProcessor and AgUiEventAdapter.
6
+ *
7
+ * @module execution/output/ag-ui-integration
8
+ */
9
+ import { ClaudeCodeOutputProcessor } from './claude-code-output-processor.js';
10
+ import { AgUiEventAdapter } from './ag-ui-adapter.js';
11
+ /**
12
+ * Create a complete AG-UI system with processor and adapter pre-wired
13
+ *
14
+ * This is the recommended way to create an AG-UI streaming system.
15
+ * It automatically:
16
+ * - Creates a ClaudeCodeOutputProcessor
17
+ * - Creates an AgUiEventAdapter with the provided runId
18
+ * - Wires the processor to emit events through the adapter
19
+ *
20
+ * @param runId - Unique identifier for this execution run
21
+ * @param threadId - Optional thread ID (defaults to runId)
22
+ * @returns Complete AG-UI system ready to process output
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const { processor, adapter } = createAgUiSystem('run-123');
27
+ *
28
+ * // Wire adapter to transport for SSE streaming
29
+ * transportManager.connectAdapter(adapter, 'run-123');
30
+ *
31
+ * // Process Claude Code output
32
+ * await processor.processLine('{"type":"assistant",...}');
33
+ *
34
+ * // Events automatically flow: processor -> adapter -> transport -> SSE clients
35
+ * ```
36
+ */
37
+ export function createAgUiSystem(runId, threadId) {
38
+ const processor = new ClaudeCodeOutputProcessor();
39
+ const adapter = new AgUiEventAdapter(runId, threadId);
40
+ // Wire processor events to adapter
41
+ adapter.connectToProcessor(processor);
42
+ return { processor, adapter };
43
+ }
44
+ /**
45
+ * Manually wire an output processor to an AG-UI adapter
46
+ *
47
+ * Use this when you need more control over processor/adapter creation.
48
+ * This function handles all the event handler registration.
49
+ *
50
+ * @param processor - Output processor to wire
51
+ * @param adapter - AG-UI adapter to receive events
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const processor = new ClaudeCodeOutputProcessor();
56
+ * const adapter = new AgUiEventAdapter('run-123');
57
+ *
58
+ * // Manually wire them together
59
+ * wireManually(processor, adapter);
60
+ *
61
+ * // Now processor events will flow to adapter
62
+ * ```
63
+ */
64
+ export function wireManually(processor, adapter) {
65
+ adapter.connectToProcessor(processor);
66
+ }
67
+ /**
68
+ * Create an AG-UI system with custom processor implementation
69
+ *
70
+ * Use this when you have a custom output processor that implements IOutputProcessor.
71
+ * The processor will be wired to a new AgUiEventAdapter.
72
+ *
73
+ * @param processor - Custom output processor implementation
74
+ * @param runId - Unique identifier for this execution run
75
+ * @param threadId - Optional thread ID (defaults to runId)
76
+ * @returns AG-UI system with your custom processor
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * class CustomProcessor implements IOutputProcessor {
81
+ * // ... your implementation
82
+ * }
83
+ *
84
+ * const processor = new CustomProcessor();
85
+ * const { processor, adapter } = createAgUiSystemWithProcessor(
86
+ * processor,
87
+ * 'run-123'
88
+ * );
89
+ * ```
90
+ */
91
+ export function createAgUiSystemWithProcessor(processor, runId, threadId) {
92
+ const adapter = new AgUiEventAdapter(runId, threadId);
93
+ adapter.connectToProcessor(processor);
94
+ return { processor, adapter };
95
+ }
96
+ //# sourceMappingURL=ag-ui-integration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ag-ui-integration.js","sourceRoot":"","sources":["../../../src/execution/output/ag-ui-integration.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAgBtD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAa,EACb,QAAiB;IAEjB,MAAM,SAAS,GAAG,IAAI,yBAAyB,EAAE,CAAC;IAClD,MAAM,OAAO,GAAG,IAAI,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAEtD,mCAAmC;IACnC,OAAO,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAEtC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAChC,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,YAAY,CAC1B,SAA2B,EAC3B,OAAyB;IAEzB,OAAO,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;AACxC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,6BAA6B,CAC3C,SAA2B,EAC3B,KAAa,EACb,QAAiB;IAEjB,MAAM,OAAO,GAAG,IAAI,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACtD,OAAO,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAEtC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAChC,CAAC"}