@northflare/runner 0.0.11 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/utils/config.d.ts +1 -0
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +13 -2
- package/dist/utils/config.js.map +1 -1
- package/package.json +1 -2
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/coverage-final.json +0 -12
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +0 -176
- package/coverage/lib/index.html +0 -116
- package/coverage/lib/preload-script.js.html +0 -964
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -196
- package/coverage/src/collections/index.html +0 -116
- package/coverage/src/collections/runner-messages.ts.html +0 -312
- package/coverage/src/components/claude-manager.ts.html +0 -1290
- package/coverage/src/components/index.html +0 -146
- package/coverage/src/components/message-handler.ts.html +0 -730
- package/coverage/src/components/repository-manager.ts.html +0 -841
- package/coverage/src/index.html +0 -131
- package/coverage/src/index.ts.html +0 -448
- package/coverage/src/runner.ts.html +0 -1239
- package/coverage/src/utils/config.ts.html +0 -780
- package/coverage/src/utils/console.ts.html +0 -121
- package/coverage/src/utils/index.html +0 -161
- package/coverage/src/utils/logger.ts.html +0 -475
- package/coverage/src/utils/status-line.ts.html +0 -445
- package/exceptions.log +0 -24
- package/lib/codex-sdk/src/codex.ts +0 -38
- package/lib/codex-sdk/src/codexOptions.ts +0 -10
- package/lib/codex-sdk/src/events.ts +0 -80
- package/lib/codex-sdk/src/exec.ts +0 -336
- package/lib/codex-sdk/src/index.ts +0 -39
- package/lib/codex-sdk/src/items.ts +0 -127
- package/lib/codex-sdk/src/outputSchemaFile.ts +0 -40
- package/lib/codex-sdk/src/thread.ts +0 -155
- package/lib/codex-sdk/src/threadOptions.ts +0 -18
- package/lib/codex-sdk/src/turnOptions.ts +0 -6
- package/lib/codex-sdk/tests/abort.test.ts +0 -165
- package/lib/codex-sdk/tests/codexExecSpy.ts +0 -37
- package/lib/codex-sdk/tests/responsesProxy.ts +0 -225
- package/lib/codex-sdk/tests/run.test.ts +0 -687
- package/lib/codex-sdk/tests/runStreamed.test.ts +0 -211
- package/lib/codex-sdk/tsconfig.json +0 -24
- package/rejections.log +0 -68
- package/runner.log +0 -488
- package/src/components/claude-sdk-manager.ts +0 -1425
- package/src/components/codex-sdk-manager.ts +0 -1358
- package/src/components/enhanced-repository-manager.ts +0 -823
- package/src/components/message-handler-sse.ts +0 -1097
- package/src/components/repository-manager.ts +0 -337
- package/src/index.ts +0 -168
- package/src/runner-sse.ts +0 -917
- package/src/services/RunnerAPIClient.ts +0 -175
- package/src/services/SSEClient.ts +0 -258
- package/src/types/claude.ts +0 -66
- package/src/types/computer-name.d.ts +0 -4
- package/src/types/index.ts +0 -64
- package/src/types/messages.ts +0 -39
- package/src/types/runner-interface.ts +0 -36
- package/src/utils/StateManager.ts +0 -187
- package/src/utils/config.ts +0 -316
- package/src/utils/console.ts +0 -15
- package/src/utils/debug.ts +0 -18
- package/src/utils/expand-env.ts +0 -22
- package/src/utils/logger.ts +0 -134
- package/src/utils/model.ts +0 -29
- package/src/utils/status-line.ts +0 -122
- package/src/utils/tool-response-sanitizer.ts +0 -160
- package/test-debug.sh +0 -26
- package/tests/retry-strategies.test.ts +0 -410
- package/tests/sdk-integration.test.ts +0 -329
- package/tests/sdk-streaming.test.ts +0 -1180
- package/tests/setup.ts +0 -5
- package/tests/test-claude-manager.ts +0 -120
- package/tests/tool-response-sanitizer.test.ts +0 -63
- package/tsconfig.json +0 -36
- package/vitest.config.ts +0 -27
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SDK Integration Test
|
|
3
|
-
*
|
|
4
|
-
* This test validates the core functionality of the new SDK-native implementation
|
|
5
|
-
* focusing on basic conversation operations that should work with the current code structure.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
9
|
-
import { ClaudeManager } from '../src/components/claude-sdk-manager';
|
|
10
|
-
import { RunnerApp } from '../src/runner-sse';
|
|
11
|
-
import { EnhancedRepositoryManager } from '../src/components/enhanced-repository-manager';
|
|
12
|
-
import type { ConversationConfig, ConversationContext, Message } from '../src/types';
|
|
13
|
-
import type { IRunnerApp } from '../src/types/runner-interface';
|
|
14
|
-
|
|
15
|
-
// Mock the Claude SDKs
|
|
16
|
-
vi.mock("@anthropic-ai/claude-code", () => ({
|
|
17
|
-
query: vi.fn(),
|
|
18
|
-
}));
|
|
19
|
-
|
|
20
|
-
// Test configuration constants
|
|
21
|
-
const TEST_CONFIG = {
|
|
22
|
-
MESSAGE_TIMEOUT_MS: 1000,
|
|
23
|
-
} as const;
|
|
24
|
-
|
|
25
|
-
// Mock data
|
|
26
|
-
const mockSessionId = 'session_integration_test_12345';
|
|
27
|
-
const mockConversationId = 'conv_integration_test_67890';
|
|
28
|
-
const mockWorkspacePath = '/tmp/test-workspace-integration';
|
|
29
|
-
const mockApiKey = 'sk-test-integration-key-12345';
|
|
30
|
-
|
|
31
|
-
const mockConversationData = {
|
|
32
|
-
id: mockConversationId,
|
|
33
|
-
objectType: 'Task',
|
|
34
|
-
objectId: 'task_integration_123',
|
|
35
|
-
model: 'claude-3-5-sonnet-20241022',
|
|
36
|
-
globalInstructions: 'You are a test assistant.',
|
|
37
|
-
workspaceInstructions: 'This is a integration test workspace.',
|
|
38
|
-
permissionsMode: 'all',
|
|
39
|
-
agentSessionId: mockSessionId,
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
const mockConfig: ConversationConfig = {
|
|
43
|
-
anthropicApiKey: mockApiKey,
|
|
44
|
-
workspaceId: 'workspace_integration_123',
|
|
45
|
-
runnerRepoPath: mockWorkspacePath,
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
// Mock runner app
|
|
49
|
-
const createMockRunner = (): IRunnerApp => ({
|
|
50
|
-
activeConversations_: new Map<string, ConversationContext>(),
|
|
51
|
-
config_: {
|
|
52
|
-
orchestratorUrl: 'http://localhost:4000',
|
|
53
|
-
dataDir: '/tmp/test-data',
|
|
54
|
-
heartbeatInterval: 30000,
|
|
55
|
-
retryStrategy: 'exponential' as const,
|
|
56
|
-
retryIntervalSecs: 5,
|
|
57
|
-
retryDurationSecs: 300,
|
|
58
|
-
},
|
|
59
|
-
getRunnerUid: vi.fn().mockReturnValue('runner_integration_test_uid'),
|
|
60
|
-
getConversationContext: vi.fn(),
|
|
61
|
-
notify: vi.fn().mockResolvedValue(undefined),
|
|
62
|
-
sendToOrchestrator: vi.fn().mockResolvedValue({ result: {} }),
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
// Mock repository manager
|
|
66
|
-
const createMockRepositoryManager = (): EnhancedRepositoryManager => ({
|
|
67
|
-
checkoutRepository: vi.fn().mockResolvedValue(mockWorkspacePath),
|
|
68
|
-
getWorkspacePath: vi.fn().mockResolvedValue(mockWorkspacePath),
|
|
69
|
-
createTaskWorktree: vi.fn().mockResolvedValue({
|
|
70
|
-
worktreePath: mockWorkspacePath,
|
|
71
|
-
cleanup: vi.fn(),
|
|
72
|
-
}),
|
|
73
|
-
createLocalTaskHandle: vi.fn().mockResolvedValue({
|
|
74
|
-
path: mockWorkspacePath,
|
|
75
|
-
cleanup: vi.fn(),
|
|
76
|
-
}),
|
|
77
|
-
} as any);
|
|
78
|
-
|
|
79
|
-
describe('SDK Integration Tests', () => {
|
|
80
|
-
let mockRunner: IRunnerApp;
|
|
81
|
-
let mockRepositoryManager: EnhancedRepositoryManager;
|
|
82
|
-
let claudeManager: ClaudeManager;
|
|
83
|
-
|
|
84
|
-
beforeEach(async () => {
|
|
85
|
-
vi.clearAllMocks();
|
|
86
|
-
|
|
87
|
-
mockRunner = createMockRunner();
|
|
88
|
-
mockRepositoryManager = createMockRepositoryManager();
|
|
89
|
-
claudeManager = new ClaudeManager(mockRunner, mockRepositoryManager);
|
|
90
|
-
|
|
91
|
-
// Mock the getConversationContext method
|
|
92
|
-
mockRunner.getConversationContext = vi.fn().mockImplementation((id) =>
|
|
93
|
-
mockRunner.activeConversations_.get(id)
|
|
94
|
-
);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
afterEach(() => {
|
|
98
|
-
// Clean up any active conversations
|
|
99
|
-
mockRunner.activeConversations_.clear();
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
describe('1. Basic SDK Manager Initialization', () => {
|
|
103
|
-
it('should create ClaudeManager instance successfully', () => {
|
|
104
|
-
expect(claudeManager).toBeInstanceOf(ClaudeManager);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it('should have required dependencies injected', () => {
|
|
108
|
-
expect(claudeManager).toHaveProperty('runner');
|
|
109
|
-
expect(claudeManager).toHaveProperty('repositoryManager');
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
describe('2. Conversation Lifecycle Management', () => {
|
|
114
|
-
it('should start a conversation with valid configuration', async () => {
|
|
115
|
-
// Mock SDK query to return a conversation-like object
|
|
116
|
-
const mockSdkQuery = vi.fn().mockImplementation(() => {
|
|
117
|
-
// Return an async iterable that simulates a conversation
|
|
118
|
-
return {
|
|
119
|
-
[Symbol.asyncIterator]: async function* () {
|
|
120
|
-
yield {
|
|
121
|
-
type: 'system',
|
|
122
|
-
message: { role: 'system', content: 'Session started' },
|
|
123
|
-
session_id: mockSessionId,
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
const mockModule = await import('@anthropic-ai/claude-code');
|
|
130
|
-
vi.mocked(mockModule.query).mockImplementation(mockSdkQuery);
|
|
131
|
-
|
|
132
|
-
// Start a conversation
|
|
133
|
-
const result = await claudeManager.startConversation(
|
|
134
|
-
'Task',
|
|
135
|
-
'task_integration_123',
|
|
136
|
-
mockConfig,
|
|
137
|
-
[{ content: 'Hello, this is a test message.' }],
|
|
138
|
-
mockConversationData
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
expect(result).toBeDefined();
|
|
142
|
-
expect(result.conversationId).toBe(mockConversationId);
|
|
143
|
-
expect(result.status).toBe('starting');
|
|
144
|
-
expect(result.conversationObjectType).toBe('Task');
|
|
145
|
-
expect(result.conversationObjectId).toBe('task_integration_123');
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it('should throw error when starting conversation without conversationData.id', async () => {
|
|
149
|
-
await expect(
|
|
150
|
-
claudeManager.startConversation(
|
|
151
|
-
'Task',
|
|
152
|
-
'task_123',
|
|
153
|
-
mockConfig,
|
|
154
|
-
[{ content: 'Test message' }],
|
|
155
|
-
// Missing conversationData
|
|
156
|
-
)
|
|
157
|
-
).rejects.toThrow('startConversation requires conversationData with a valid conversation.id');
|
|
158
|
-
});
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
describe('3. Message Sending Functionality', () => {
|
|
162
|
-
it('should handle sendUserMessage gracefully', async () => {
|
|
163
|
-
// Create a mock conversation context
|
|
164
|
-
const mockConversation = {
|
|
165
|
-
send: vi.fn().mockResolvedValue(undefined),
|
|
166
|
-
end: vi.fn().mockResolvedValue(undefined),
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
const context: ConversationContext = {
|
|
170
|
-
conversationId: mockConversationId,
|
|
171
|
-
agentSessionId: mockSessionId,
|
|
172
|
-
conversationObjectType: 'Task',
|
|
173
|
-
conversationObjectId: 'task_123',
|
|
174
|
-
status: 'active',
|
|
175
|
-
config: mockConfig,
|
|
176
|
-
startedAt: new Date(),
|
|
177
|
-
lastActivityAt: new Date(),
|
|
178
|
-
conversation: mockConversation as any,
|
|
179
|
-
model: 'claude-3-5-sonnet-20241022',
|
|
180
|
-
globalInstructions: '',
|
|
181
|
-
workspaceInstructions: '',
|
|
182
|
-
permissionsMode: 'all',
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
mockRunner.activeConversations_.set(mockConversationId, context);
|
|
186
|
-
|
|
187
|
-
// Test sending a message
|
|
188
|
-
await claudeManager.sendUserMessage(mockConversationId, 'Test message');
|
|
189
|
-
|
|
190
|
-
expect(mockConversation.send).toHaveBeenCalledWith({
|
|
191
|
-
type: 'text',
|
|
192
|
-
text: 'Test message',
|
|
193
|
-
});
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
it('should throw error for non-existent conversation', async () => {
|
|
197
|
-
// Try to send message to non-existent conversation
|
|
198
|
-
await expect(
|
|
199
|
-
claudeManager.sendUserMessage('non_existent_id', 'Test message')
|
|
200
|
-
).rejects.toThrow('No active or fetchable conversation found for non_existent_id');
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
describe('4. Error Handling', () => {
|
|
205
|
-
it('should validate required conversationData', async () => {
|
|
206
|
-
// Test with missing conversationData
|
|
207
|
-
await expect(
|
|
208
|
-
claudeManager.startConversation(
|
|
209
|
-
'Task',
|
|
210
|
-
'task_123',
|
|
211
|
-
mockConfig,
|
|
212
|
-
[{ content: 'Test message' }],
|
|
213
|
-
undefined // Missing conversationData
|
|
214
|
-
)
|
|
215
|
-
).rejects.toThrow('startConversation requires conversationData with a valid conversation.id');
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
it('should handle repository manager errors during task handle creation', async () => {
|
|
219
|
-
// Mock repository manager to throw error on createLocalTaskHandle
|
|
220
|
-
const errorRepo = createMockRepositoryManager();
|
|
221
|
-
vi.mocked(errorRepo.createLocalTaskHandle).mockRejectedValue(new Error('Repository not found'));
|
|
222
|
-
|
|
223
|
-
const errorManager = new ClaudeManager(mockRunner, errorRepo);
|
|
224
|
-
|
|
225
|
-
await expect(
|
|
226
|
-
errorManager.startConversation(
|
|
227
|
-
'Task',
|
|
228
|
-
'task_123',
|
|
229
|
-
mockConfig,
|
|
230
|
-
[{ content: 'Test message' }],
|
|
231
|
-
mockConversationData
|
|
232
|
-
)
|
|
233
|
-
).rejects.toThrow('Repository not found');
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
describe('5. State Management', () => {
|
|
238
|
-
it('should track active conversations correctly', async () => {
|
|
239
|
-
// Initial state should have no conversations
|
|
240
|
-
expect(mockRunner.activeConversations_.size).toBe(0);
|
|
241
|
-
|
|
242
|
-
// Mock SDK query for conversation start
|
|
243
|
-
const mockSdkQuery = vi.fn().mockImplementation(() => ({
|
|
244
|
-
[Symbol.asyncIterator]: async function* () {
|
|
245
|
-
yield {
|
|
246
|
-
type: 'system',
|
|
247
|
-
message: { role: 'system', content: 'Session started' },
|
|
248
|
-
session_id: mockSessionId,
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
}));
|
|
252
|
-
|
|
253
|
-
const mockModule = await import('@anthropic-ai/claude-code');
|
|
254
|
-
vi.mocked(mockModule.query).mockImplementation(mockSdkQuery);
|
|
255
|
-
|
|
256
|
-
// Start a conversation
|
|
257
|
-
await claudeManager.startConversation(
|
|
258
|
-
'Task',
|
|
259
|
-
'task_state_123',
|
|
260
|
-
mockConfig,
|
|
261
|
-
[{ content: 'State test message' }],
|
|
262
|
-
{ ...mockConversationData, objectId: 'task_state_123' }
|
|
263
|
-
);
|
|
264
|
-
|
|
265
|
-
// Should now have one active conversation
|
|
266
|
-
expect(mockRunner.activeConversations_.size).toBe(1);
|
|
267
|
-
|
|
268
|
-
const context = mockRunner.activeConversations_.get(mockConversationId);
|
|
269
|
-
expect(context).toBeDefined();
|
|
270
|
-
expect(context?.conversationObjectId).toBe('task_state_123');
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
it('should update conversation status appropriately', async () => {
|
|
274
|
-
// Create conversation context
|
|
275
|
-
const context: ConversationContext = {
|
|
276
|
-
conversationId: mockConversationId,
|
|
277
|
-
agentSessionId: mockSessionId,
|
|
278
|
-
conversationObjectType: 'Task',
|
|
279
|
-
conversationObjectId: 'task_123',
|
|
280
|
-
status: 'starting', // Initial status
|
|
281
|
-
config: mockConfig,
|
|
282
|
-
startedAt: new Date(),
|
|
283
|
-
lastActivityAt: new Date(),
|
|
284
|
-
model: 'claude-3-5-sonnet-20241022',
|
|
285
|
-
globalInstructions: '',
|
|
286
|
-
workspaceInstructions: '',
|
|
287
|
-
permissionsMode: 'all',
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
mockRunner.activeConversations_.set(mockConversationId, context);
|
|
291
|
-
|
|
292
|
-
// Verify initial status
|
|
293
|
-
expect(context.status).toBe('starting');
|
|
294
|
-
|
|
295
|
-
// Status should be updated during conversation operations
|
|
296
|
-
// This is tested implicitly through the conversation lifecycle
|
|
297
|
-
});
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
describe('6. Integration with Repository Manager', () => {
|
|
301
|
-
it('should use repository manager for task handle creation', async () => {
|
|
302
|
-
// Mock SDK query
|
|
303
|
-
const mockSdkQuery = vi.fn().mockImplementation(() => ({
|
|
304
|
-
[Symbol.asyncIterator]: async function* () {
|
|
305
|
-
yield {
|
|
306
|
-
type: 'system',
|
|
307
|
-
message: { role: 'system', content: 'Session started' },
|
|
308
|
-
session_id: mockSessionId,
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
}));
|
|
312
|
-
|
|
313
|
-
const mockModule = await import('@anthropic-ai/claude-code');
|
|
314
|
-
vi.mocked(mockModule.query).mockImplementation(mockSdkQuery);
|
|
315
|
-
|
|
316
|
-
// Start conversation (should call repository manager)
|
|
317
|
-
await claudeManager.startConversation(
|
|
318
|
-
'Task',
|
|
319
|
-
'task_repo_123',
|
|
320
|
-
mockConfig,
|
|
321
|
-
[{ content: 'Repository test message' }],
|
|
322
|
-
{ ...mockConversationData, objectId: 'task_repo_123' }
|
|
323
|
-
);
|
|
324
|
-
|
|
325
|
-
// Verify repository manager was called for creating task handle
|
|
326
|
-
expect(mockRepositoryManager.createLocalTaskHandle).toHaveBeenCalled();
|
|
327
|
-
});
|
|
328
|
-
});
|
|
329
|
-
});
|