tarsk 0.2.5 → 0.3.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 (119) hide show
  1. package/README.md +1 -7
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.js +92 -32
  4. package/dist/lib/response-builder.d.ts +50 -0
  5. package/dist/lib/response-builder.js +56 -0
  6. package/dist/lib/stream-helper.d.ts +39 -0
  7. package/dist/lib/stream-helper.js +43 -0
  8. package/dist/managers/ConversationManager.d.ts +83 -0
  9. package/dist/managers/ConversationManager.js +129 -0
  10. package/dist/managers/GitManager.d.ts +133 -0
  11. package/dist/managers/GitManager.js +330 -0
  12. package/dist/managers/MetadataManager.d.ts +139 -0
  13. package/dist/managers/MetadataManager.js +309 -0
  14. package/dist/managers/ModelManager.d.ts +57 -0
  15. package/dist/managers/ModelManager.js +129 -0
  16. package/dist/managers/NeovateExecutor.d.ts +40 -0
  17. package/dist/managers/NeovateExecutor.js +138 -0
  18. package/dist/managers/ProjectManager.d.ts +162 -0
  19. package/dist/managers/ProjectManager.js +353 -0
  20. package/dist/managers/ThreadManager.d.ts +181 -0
  21. package/dist/managers/ThreadManager.js +325 -0
  22. package/dist/managers/conversation-manager.d.ts +83 -0
  23. package/dist/managers/conversation-manager.js +129 -0
  24. package/dist/managers/git-manager.d.ts +133 -0
  25. package/dist/managers/git-manager.js +330 -0
  26. package/dist/managers/metadata-manager.d.ts +139 -0
  27. package/dist/managers/metadata-manager.js +305 -0
  28. package/dist/managers/model-manager.d.ts +59 -0
  29. package/dist/managers/model-manager.js +144 -0
  30. package/dist/managers/neovate-executor.d.ts +43 -0
  31. package/dist/managers/neovate-executor.js +205 -0
  32. package/dist/managers/processing-state-manager.d.ts +40 -0
  33. package/dist/managers/processing-state-manager.js +27 -0
  34. package/dist/managers/project-manager.d.ts +199 -0
  35. package/dist/managers/project-manager.js +465 -0
  36. package/dist/managers/thread-manager.d.ts +193 -0
  37. package/dist/managers/thread-manager.js +368 -0
  38. package/dist/model-info-aihubmix.d.ts +25 -0
  39. package/dist/model-info-aihubmix.js +117 -0
  40. package/dist/model-info-openai.d.ts +17 -0
  41. package/dist/model-info-openai.js +59 -0
  42. package/dist/model-info-openrouter.d.ts +25 -0
  43. package/dist/model-info-openrouter.js +101 -0
  44. package/dist/model-info.d.ts +37 -0
  45. package/dist/model-info.js +39 -0
  46. package/dist/provider-data.d.ts +101 -0
  47. package/dist/provider-data.js +471 -0
  48. package/dist/provider.d.ts +10 -0
  49. package/dist/provider.js +192 -0
  50. package/dist/public/android-chrome-192x192.png +0 -0
  51. package/dist/public/android-chrome-512x512.png +0 -0
  52. package/dist/public/apple-touch-icon.png +0 -0
  53. package/dist/public/assets/index-B443aj9k.js +8506 -0
  54. package/dist/public/assets/index-CjXGVbI7.css +1 -0
  55. package/dist/public/assets/index-DJC-p914.js +8506 -0
  56. package/dist/public/favicon-16x16.png +0 -0
  57. package/dist/public/favicon-32x32.png +0 -0
  58. package/dist/public/favicon.ico +0 -0
  59. package/dist/public/index.html +28 -0
  60. package/dist/public/manifest.json +82 -0
  61. package/dist/public/placeholder-logo.svg +1 -0
  62. package/dist/public/placeholder.svg +1 -0
  63. package/dist/public/snpro.woff2 +0 -0
  64. package/dist/public/tarsk-color.svg +12 -0
  65. package/dist/public/tarsk.png +0 -0
  66. package/dist/public/tarsk.svg +12 -0
  67. package/dist/public/zalando-sans.woff2 +0 -0
  68. package/dist/routes/chat-old.d.ts +21 -0
  69. package/dist/routes/chat-old.js +251 -0
  70. package/dist/routes/chat.d.ts +21 -0
  71. package/dist/routes/chat.js +217 -0
  72. package/dist/routes/git.d.ts +4 -0
  73. package/dist/routes/git.js +668 -0
  74. package/dist/routes/models.d.ts +18 -0
  75. package/dist/routes/models.js +128 -0
  76. package/dist/routes/projects-old.d.ts +20 -0
  77. package/dist/routes/projects-old.js +297 -0
  78. package/dist/routes/projects.d.ts +20 -0
  79. package/dist/routes/projects.js +365 -0
  80. package/dist/routes/providers.d.ts +15 -0
  81. package/dist/routes/providers.js +130 -0
  82. package/dist/routes/threads-old.d.ts +14 -0
  83. package/dist/routes/threads-old.js +393 -0
  84. package/dist/routes/threads.d.ts +14 -0
  85. package/dist/routes/threads.js +352 -0
  86. package/dist/types/models.d.ts +315 -0
  87. package/dist/types/models.js +11 -0
  88. package/dist/utils/env-manager.d.ts +3 -0
  89. package/dist/utils/env-manager.js +60 -0
  90. package/dist/utils/open-router-models.d.ts +45 -0
  91. package/dist/utils/open-router-models.js +103 -0
  92. package/dist/utils/openai-models.d.ts +63 -0
  93. package/dist/utils/openai-models.js +152 -0
  94. package/dist/utils/openai-pricing-scraper.d.ts +17 -0
  95. package/dist/utils/openai-pricing-scraper.js +185 -0
  96. package/dist/utils/validation.d.ts +10 -0
  97. package/dist/utils/validation.js +20 -0
  98. package/dist/utils.d.ts +10 -0
  99. package/dist/utils.js +12 -0
  100. package/package.json +36 -22
  101. package/LICENSE.md +0 -7
  102. package/dist/agent/agent.js +0 -131
  103. package/dist/agent/interfaces.js +0 -1
  104. package/dist/api/encryption.js +0 -41
  105. package/dist/api/models.js +0 -169
  106. package/dist/api/prompt.js +0 -12
  107. package/dist/api/settings.js +0 -43
  108. package/dist/api/test.js +0 -29
  109. package/dist/api/tools.js +0 -287
  110. package/dist/api/utils.js +0 -18
  111. package/dist/interfaces/meta.js +0 -1
  112. package/dist/interfaces/model.js +0 -1
  113. package/dist/interfaces/settings.js +0 -1
  114. package/dist/log/log.js +0 -33
  115. package/dist/prompt.js +0 -49
  116. package/dist/tools.js +0 -84
  117. package/dist/utils/files.js +0 -14
  118. package/dist/utils/json-file.js +0 -28
  119. package/dist/utils/strip-markdown.js +0 -5
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Chat routes for the REST API
3
+ *
4
+ * Handles chat message processing:
5
+ * - POST /api/chat - Send a message to the agent
6
+ */
7
+ import { Hono } from 'hono';
8
+ import { delay } from '../utils.js';
9
+ import { streamAsyncGenerator } from '../lib/stream-helper.js';
10
+ import { ResponseBuilder } from '../lib/response-builder.js';
11
+ /**
12
+ * Creates chat routes
13
+ * @param threadManager - The ThreadManager instance
14
+ * @param neovateExecutor - The NeovateExecutor instance
15
+ * @param conversationManager - The ConversationManager instance
16
+ * @param processingStateManager - The ProcessingStateManager instance
17
+ * @returns Hono router with chat routes
18
+ */
19
+ export function createChatRoutes(threadManager, neovateExecutor, conversationManager, processingStateManager) {
20
+ const router = new Hono();
21
+ /**
22
+ * POST /api/chat
23
+ * Send a message to the agent
24
+ *
25
+ * Request body:
26
+ * {
27
+ * "threadId": "uuid",
28
+ * "message": "User message content",
29
+ * "model": "model-name",
30
+ * "attachments": [
31
+ * {
32
+ * "name": "file.txt",
33
+ * "content": "base64-encoded-content",
34
+ * "size": 1024,
35
+ * "mimeType": "text/plain"
36
+ * }
37
+ * ]
38
+ * }
39
+ *
40
+ * Response: Newline-delimited JSON stream of NeovateEvent objects
41
+ *
42
+ * Requirements:
43
+ * - 6.4 - THE CLI SHALL expose REST API endpoints for chat message processing
44
+ * - 8.5 - WHEN sending a chat message, THE App SHALL send a POST request with the message content and Selected_Thread context to the CLI
45
+ * - 5.4 - WHEN the Neovate command executes, THE CLI SHALL stream the output back to the App
46
+ */
47
+ router.post('/', async (c) => {
48
+ try {
49
+ const body = await c.req.json();
50
+ const { threadId, content, model: baseModel, provider, attachments, planMode } = body;
51
+ // Prepend provider name (lowercased) to the model if provider is provided
52
+ let model = baseModel;
53
+ if (provider && typeof provider === 'string') {
54
+ const providerPrefix = provider.toLowerCase();
55
+ // Only prepend if the model doesn't already start with this provider prefix
56
+ if (!model.startsWith(providerPrefix + '/')) {
57
+ model = `${providerPrefix}/${model}`;
58
+ }
59
+ }
60
+ // Validate required fields
61
+ if (!threadId || typeof threadId !== 'string') {
62
+ const { response, statusCode } = ResponseBuilder.error('INVALID_REQUEST', 'threadId is required and must be a string', 400);
63
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
+ return c.json(response, statusCode);
65
+ }
66
+ if (!content || typeof content !== 'string') {
67
+ const { response, statusCode } = ResponseBuilder.error('INVALID_REQUEST', 'content is required and must be a string', 400);
68
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
+ return c.json(response, statusCode);
70
+ }
71
+ if (!model || typeof model !== 'string') {
72
+ const { response, statusCode } = ResponseBuilder.error('INVALID_REQUEST', 'model is required and must be a string', 400);
73
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
74
+ return c.json(response, statusCode);
75
+ }
76
+ // Get thread metadata to build execution context
77
+ const thread = await threadManager.getThread(threadId);
78
+ if (!thread) {
79
+ const { response, statusCode } = ResponseBuilder.error('THREAD_NOT_FOUND', `Thread not found: ${threadId}`, 404);
80
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
81
+ return c.json(response, statusCode);
82
+ }
83
+ // Capture thread path for use in generators
84
+ const threadPath = thread.path;
85
+ // Check if this is a replay request
86
+ if (content.trim().toLowerCase() === 'replay') {
87
+ console.log('[ChatRoute] Replay request detected');
88
+ // Get the last message from conversation history
89
+ const lastMessages = await conversationManager.getLastMessages(threadPath, 1);
90
+ if (lastMessages.length === 0) {
91
+ const { response, statusCode } = ResponseBuilder.error('NO_HISTORY', 'No previous conversation found to replay', 404);
92
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
93
+ return c.json(response, statusCode);
94
+ }
95
+ const lastMessage = lastMessages[0];
96
+ // Check if message has a completed response
97
+ if (!lastMessage.response) {
98
+ const { response, statusCode } = ResponseBuilder.error('NO_RESPONSE', 'Previous message has no completed response to replay', 404);
99
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
100
+ return c.json(response, statusCode);
101
+ }
102
+ console.log('[ChatRoute] Replaying message:', {
103
+ messageId: lastMessage.id,
104
+ timestamp: lastMessage.timestamp,
105
+ eventCount: lastMessage.response.events.length,
106
+ });
107
+ // Extract response to ensure TypeScript narrowing
108
+ const response = lastMessage.response;
109
+ // Create a generator for replay events
110
+ async function* replayGenerator() {
111
+ // First, send a replay indicator event
112
+ const replayEvent = {
113
+ type: 'message',
114
+ role: 'system',
115
+ content: `🔄 Replaying previous conversation from ${lastMessage.timestamp}`
116
+ };
117
+ await delay(1000);
118
+ yield replayEvent;
119
+ // Then stream all the captured events
120
+ for (const event of response.events) {
121
+ console.log('[ChatRoute] Replaying event:', event);
122
+ await delay(1000);
123
+ yield event;
124
+ }
125
+ // Finally, send a completion indicator
126
+ const completeEvent = {
127
+ type: 'message',
128
+ role: 'system',
129
+ content: '✅ Replay complete'
130
+ };
131
+ await delay(1000);
132
+ yield completeEvent;
133
+ }
134
+ return streamAsyncGenerator(c, replayGenerator());
135
+ }
136
+ // Normal chat flow - capture and execute
137
+ // Build execution context
138
+ const context = {
139
+ threadId,
140
+ threadPath,
141
+ model,
142
+ provider,
143
+ attachments,
144
+ planMode,
145
+ };
146
+ console.log('[ChatRoute] Execution context:', {
147
+ threadId,
148
+ threadPath,
149
+ model,
150
+ planMode,
151
+ attachmentCount: attachments?.length || 0,
152
+ });
153
+ // Start capturing the conversation
154
+ const messageId = await conversationManager.startMessage(threadId, threadPath, content, model, attachments, planMode);
155
+ // Mark thread as processing
156
+ processingStateManager.setProcessing(threadId);
157
+ // Create a generator for chat execution events
158
+ async function* chatExecutionGenerator() {
159
+ const capturedEvents = [];
160
+ let fullContent = '';
161
+ try {
162
+ for await (const event of neovateExecutor.execute(content, context)) {
163
+ // Capture the event
164
+ capturedEvents.push(event);
165
+ // Accumulate content from message events
166
+ if (event.type === 'message' && event.content) {
167
+ fullContent += event.content;
168
+ }
169
+ // Yield the event for streaming
170
+ yield event;
171
+ }
172
+ // Complete the conversation message with captured data
173
+ await conversationManager.completeMessage(threadPath, messageId, fullContent, capturedEvents);
174
+ console.log('[ChatRoute] Conversation captured:', {
175
+ messageId,
176
+ eventCount: capturedEvents.length,
177
+ contentLength: fullContent.length,
178
+ });
179
+ }
180
+ catch (error) {
181
+ const errorMessage = error instanceof Error ? error.message : String(error);
182
+ const errorEvent = {
183
+ type: 'error',
184
+ content: errorMessage,
185
+ error: {
186
+ code: 'STREAM_ERROR',
187
+ message: errorMessage,
188
+ details: error instanceof Error ? { stack: error.stack } : undefined
189
+ }
190
+ };
191
+ // Capture the error event too
192
+ capturedEvents.push(errorEvent);
193
+ yield errorEvent;
194
+ // Try to save the partial conversation even on error
195
+ try {
196
+ await conversationManager.completeMessage(threadPath, messageId, fullContent, capturedEvents);
197
+ }
198
+ catch (saveError) {
199
+ console.error('[ChatRoute] Failed to save partial conversation:', saveError);
200
+ }
201
+ }
202
+ finally {
203
+ // Clear processing state when done
204
+ processingStateManager.clearProcessing(threadId);
205
+ }
206
+ }
207
+ return streamAsyncGenerator(c, chatExecutionGenerator());
208
+ }
209
+ catch (error) {
210
+ const { response, statusCode } = ResponseBuilder.error('REQUEST_PARSE_ERROR', 'Failed to parse request body', 400, error instanceof Error ? error.message : String(error));
211
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
212
+ return c.json(response, statusCode);
213
+ }
214
+ });
215
+ return router;
216
+ }
217
+ //# sourceMappingURL=chat.js.map
@@ -0,0 +1,4 @@
1
+ import { Hono } from 'hono';
2
+ import { MetadataManager } from '../managers/metadata-manager.js';
3
+ export declare function createGitRoutes(metadataManager: MetadataManager): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
4
+ //# sourceMappingURL=git.d.ts.map