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.
- package/README.md +1 -7
- package/dist/index.d.ts +3 -0
- package/dist/index.js +92 -32
- package/dist/lib/response-builder.d.ts +50 -0
- package/dist/lib/response-builder.js +56 -0
- package/dist/lib/stream-helper.d.ts +39 -0
- package/dist/lib/stream-helper.js +43 -0
- package/dist/managers/ConversationManager.d.ts +83 -0
- package/dist/managers/ConversationManager.js +129 -0
- package/dist/managers/GitManager.d.ts +133 -0
- package/dist/managers/GitManager.js +330 -0
- package/dist/managers/MetadataManager.d.ts +139 -0
- package/dist/managers/MetadataManager.js +309 -0
- package/dist/managers/ModelManager.d.ts +57 -0
- package/dist/managers/ModelManager.js +129 -0
- package/dist/managers/NeovateExecutor.d.ts +40 -0
- package/dist/managers/NeovateExecutor.js +138 -0
- package/dist/managers/ProjectManager.d.ts +162 -0
- package/dist/managers/ProjectManager.js +353 -0
- package/dist/managers/ThreadManager.d.ts +181 -0
- package/dist/managers/ThreadManager.js +325 -0
- package/dist/managers/conversation-manager.d.ts +83 -0
- package/dist/managers/conversation-manager.js +129 -0
- package/dist/managers/git-manager.d.ts +133 -0
- package/dist/managers/git-manager.js +330 -0
- package/dist/managers/metadata-manager.d.ts +139 -0
- package/dist/managers/metadata-manager.js +305 -0
- package/dist/managers/model-manager.d.ts +59 -0
- package/dist/managers/model-manager.js +144 -0
- package/dist/managers/neovate-executor.d.ts +43 -0
- package/dist/managers/neovate-executor.js +205 -0
- package/dist/managers/processing-state-manager.d.ts +40 -0
- package/dist/managers/processing-state-manager.js +27 -0
- package/dist/managers/project-manager.d.ts +199 -0
- package/dist/managers/project-manager.js +465 -0
- package/dist/managers/thread-manager.d.ts +193 -0
- package/dist/managers/thread-manager.js +368 -0
- package/dist/model-info-aihubmix.d.ts +25 -0
- package/dist/model-info-aihubmix.js +117 -0
- package/dist/model-info-openai.d.ts +17 -0
- package/dist/model-info-openai.js +59 -0
- package/dist/model-info-openrouter.d.ts +25 -0
- package/dist/model-info-openrouter.js +101 -0
- package/dist/model-info.d.ts +37 -0
- package/dist/model-info.js +39 -0
- package/dist/provider-data.d.ts +101 -0
- package/dist/provider-data.js +471 -0
- package/dist/provider.d.ts +10 -0
- package/dist/provider.js +192 -0
- package/dist/public/android-chrome-192x192.png +0 -0
- package/dist/public/android-chrome-512x512.png +0 -0
- package/dist/public/apple-touch-icon.png +0 -0
- package/dist/public/assets/index-B443aj9k.js +8506 -0
- package/dist/public/assets/index-CjXGVbI7.css +1 -0
- package/dist/public/assets/index-DJC-p914.js +8506 -0
- package/dist/public/favicon-16x16.png +0 -0
- package/dist/public/favicon-32x32.png +0 -0
- package/dist/public/favicon.ico +0 -0
- package/dist/public/index.html +28 -0
- package/dist/public/manifest.json +82 -0
- package/dist/public/placeholder-logo.svg +1 -0
- package/dist/public/placeholder.svg +1 -0
- package/dist/public/snpro.woff2 +0 -0
- package/dist/public/tarsk-color.svg +12 -0
- package/dist/public/tarsk.png +0 -0
- package/dist/public/tarsk.svg +12 -0
- package/dist/public/zalando-sans.woff2 +0 -0
- package/dist/routes/chat-old.d.ts +21 -0
- package/dist/routes/chat-old.js +251 -0
- package/dist/routes/chat.d.ts +21 -0
- package/dist/routes/chat.js +217 -0
- package/dist/routes/git.d.ts +4 -0
- package/dist/routes/git.js +668 -0
- package/dist/routes/models.d.ts +18 -0
- package/dist/routes/models.js +128 -0
- package/dist/routes/projects-old.d.ts +20 -0
- package/dist/routes/projects-old.js +297 -0
- package/dist/routes/projects.d.ts +20 -0
- package/dist/routes/projects.js +365 -0
- package/dist/routes/providers.d.ts +15 -0
- package/dist/routes/providers.js +130 -0
- package/dist/routes/threads-old.d.ts +14 -0
- package/dist/routes/threads-old.js +393 -0
- package/dist/routes/threads.d.ts +14 -0
- package/dist/routes/threads.js +352 -0
- package/dist/types/models.d.ts +315 -0
- package/dist/types/models.js +11 -0
- package/dist/utils/env-manager.d.ts +3 -0
- package/dist/utils/env-manager.js +60 -0
- package/dist/utils/open-router-models.d.ts +45 -0
- package/dist/utils/open-router-models.js +103 -0
- package/dist/utils/openai-models.d.ts +63 -0
- package/dist/utils/openai-models.js +152 -0
- package/dist/utils/openai-pricing-scraper.d.ts +17 -0
- package/dist/utils/openai-pricing-scraper.js +185 -0
- package/dist/utils/validation.d.ts +10 -0
- package/dist/utils/validation.js +20 -0
- package/dist/utils.d.ts +10 -0
- package/dist/utils.js +12 -0
- package/package.json +36 -22
- package/LICENSE.md +0 -7
- package/dist/agent/agent.js +0 -131
- package/dist/agent/interfaces.js +0 -1
- package/dist/api/encryption.js +0 -41
- package/dist/api/models.js +0 -169
- package/dist/api/prompt.js +0 -12
- package/dist/api/settings.js +0 -43
- package/dist/api/test.js +0 -29
- package/dist/api/tools.js +0 -287
- package/dist/api/utils.js +0 -18
- package/dist/interfaces/meta.js +0 -1
- package/dist/interfaces/model.js +0 -1
- package/dist/interfaces/settings.js +0 -1
- package/dist/log/log.js +0 -33
- package/dist/prompt.js +0 -49
- package/dist/tools.js +0 -84
- package/dist/utils/files.js +0 -14
- package/dist/utils/json-file.js +0 -28
- 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
|