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,393 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thread routes for the REST API
|
|
3
|
+
*
|
|
4
|
+
* Handles all thread-related operations:
|
|
5
|
+
* - POST /api/threads - Create a new thread
|
|
6
|
+
* - GET /api/threads?projectId=xxx - List threads for a project
|
|
7
|
+
* - DELETE /api/threads/:id - Delete a thread
|
|
8
|
+
*/
|
|
9
|
+
import { Hono } from 'hono';
|
|
10
|
+
import { validateThreadName } from '../utils/validation.js';
|
|
11
|
+
import { streamAsyncGenerator } from '../lib/stream-helper.js';
|
|
12
|
+
const extractTextBlocksFromContent = (content) => {
|
|
13
|
+
const trimmed = content.trim();
|
|
14
|
+
if (!trimmed.startsWith('[') && !trimmed.startsWith('{')) {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
const parsed = JSON.parse(trimmed);
|
|
19
|
+
if (Array.isArray(parsed)) {
|
|
20
|
+
return parsed
|
|
21
|
+
.filter((block) => block && typeof block === 'object' && block.type === 'text')
|
|
22
|
+
.map((block) => (typeof block.text === 'string' ? block.text : ''))
|
|
23
|
+
.filter((text) => text.length > 0);
|
|
24
|
+
}
|
|
25
|
+
if (parsed && typeof parsed === 'object' && typeof parsed.text === 'string') {
|
|
26
|
+
return [parsed.text];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
return [];
|
|
33
|
+
};
|
|
34
|
+
const extractAssistantContent = (events, fallback) => {
|
|
35
|
+
if (!events || events.length === 0) {
|
|
36
|
+
return fallback;
|
|
37
|
+
}
|
|
38
|
+
const resultEvent = [...events].reverse().find((event) => event.type === 'result');
|
|
39
|
+
if (resultEvent && typeof resultEvent.content === 'string' && resultEvent.content.trim().length > 0) {
|
|
40
|
+
return resultEvent.content;
|
|
41
|
+
}
|
|
42
|
+
const assistantMessages = events.filter((event) => event.type === 'message' && event.role === 'assistant');
|
|
43
|
+
let lastTextBlock = null;
|
|
44
|
+
const assistantChunks = [];
|
|
45
|
+
for (const event of assistantMessages) {
|
|
46
|
+
if (typeof event.content !== 'string') {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
assistantChunks.push(event.content);
|
|
50
|
+
const textBlocks = extractTextBlocksFromContent(event.content);
|
|
51
|
+
if (textBlocks.length > 0) {
|
|
52
|
+
lastTextBlock = textBlocks[textBlocks.length - 1];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (lastTextBlock) {
|
|
56
|
+
return lastTextBlock;
|
|
57
|
+
}
|
|
58
|
+
if (assistantChunks.length === 0) {
|
|
59
|
+
return fallback;
|
|
60
|
+
}
|
|
61
|
+
const combined = assistantChunks.join('');
|
|
62
|
+
return combined.trim().length > 0 ? combined : fallback;
|
|
63
|
+
};
|
|
64
|
+
export function createThreadRoutes(threadManager, gitManager, conversationManager) {
|
|
65
|
+
const router = new Hono();
|
|
66
|
+
/**
|
|
67
|
+
* POST /api/threads
|
|
68
|
+
* Create a new thread for a project
|
|
69
|
+
*
|
|
70
|
+
* Request body:
|
|
71
|
+
* {
|
|
72
|
+
* "projectId": "uuid",
|
|
73
|
+
* "title": "Optional thread title"
|
|
74
|
+
* }
|
|
75
|
+
*
|
|
76
|
+
* Response: Newline-delimited JSON stream of ThreadEvent objects
|
|
77
|
+
*
|
|
78
|
+
* Requirements:
|
|
79
|
+
* - 6.3 - THE CLI SHALL expose REST API endpoints for Thread operations
|
|
80
|
+
* - 8.3 - WHEN creating a Thread, THE App SHALL send a POST request with the Project identifier to the CLI
|
|
81
|
+
* - 8.4 - THE CLI SHALL support streaming responses to the client
|
|
82
|
+
*/
|
|
83
|
+
router.post('/', async (c) => {
|
|
84
|
+
try {
|
|
85
|
+
const body = await c.req.json();
|
|
86
|
+
const { projectId, title } = body;
|
|
87
|
+
// Validate projectId is provided
|
|
88
|
+
if (!projectId || typeof projectId !== 'string') {
|
|
89
|
+
const errorResponse = {
|
|
90
|
+
error: {
|
|
91
|
+
code: 'INVALID_REQUEST',
|
|
92
|
+
message: 'projectId is required and must be a string',
|
|
93
|
+
timestamp: new Date().toISOString()
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
return c.json(errorResponse, 400);
|
|
97
|
+
}
|
|
98
|
+
// Validate title if provided
|
|
99
|
+
if (title !== undefined && typeof title !== 'string') {
|
|
100
|
+
const errorResponse = {
|
|
101
|
+
error: {
|
|
102
|
+
code: 'INVALID_REQUEST',
|
|
103
|
+
message: 'title must be a string if provided',
|
|
104
|
+
timestamp: new Date().toISOString()
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
return c.json(errorResponse, 400);
|
|
108
|
+
}
|
|
109
|
+
// Validate thread name (empty/whitespace is allowed, will auto-generate)
|
|
110
|
+
if (title && title.trim() !== '') {
|
|
111
|
+
const nameError = validateThreadName(title);
|
|
112
|
+
if (nameError) {
|
|
113
|
+
const errorResponse = {
|
|
114
|
+
error: {
|
|
115
|
+
code: 'INVALID_REQUEST',
|
|
116
|
+
message: nameError,
|
|
117
|
+
timestamp: new Date().toISOString()
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
return c.json(errorResponse, 400);
|
|
121
|
+
}
|
|
122
|
+
// Check for duplicate branch names
|
|
123
|
+
const existingThreads = await threadManager.listThreads(projectId);
|
|
124
|
+
const sanitizedNewName = gitManager.sanitizeBranchName(title);
|
|
125
|
+
const existingSanitized = existingThreads.map(t => gitManager.sanitizeBranchName(t.title));
|
|
126
|
+
if (existingSanitized.includes(sanitizedNewName)) {
|
|
127
|
+
const errorResponse = {
|
|
128
|
+
error: {
|
|
129
|
+
code: 'DUPLICATE_BRANCH',
|
|
130
|
+
message: `A thread with branch name "${sanitizedNewName}" already exists`,
|
|
131
|
+
timestamp: new Date().toISOString()
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
return c.json(errorResponse, 409);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Stream the thread creation events
|
|
138
|
+
return streamAsyncGenerator(c, threadManager.createThread(projectId, title));
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
const errorResponse = {
|
|
142
|
+
error: {
|
|
143
|
+
code: 'REQUEST_PARSE_ERROR',
|
|
144
|
+
message: 'Failed to parse request body',
|
|
145
|
+
details: error instanceof Error ? error.message : String(error),
|
|
146
|
+
timestamp: new Date().toISOString()
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
return c.json(errorResponse, 400);
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
/**
|
|
153
|
+
* GET /api/threads?projectId=xxx
|
|
154
|
+
* List all threads for a specific project
|
|
155
|
+
*
|
|
156
|
+
* Query parameters:
|
|
157
|
+
* - projectId (required): The project ID to filter threads
|
|
158
|
+
*
|
|
159
|
+
* Response:
|
|
160
|
+
* [
|
|
161
|
+
* {
|
|
162
|
+
* "id": "uuid",
|
|
163
|
+
* "projectId": "uuid",
|
|
164
|
+
* "title": "Thread title",
|
|
165
|
+
* "path": "/path/to/thread",
|
|
166
|
+
* "currentBranch": "branch-name",
|
|
167
|
+
* "createdAt": "2024-01-01T00:00:00Z"
|
|
168
|
+
* }
|
|
169
|
+
* ]
|
|
170
|
+
*
|
|
171
|
+
* Requirements:
|
|
172
|
+
* - 6.3 - THE CLI SHALL expose REST API endpoints for Thread operations
|
|
173
|
+
*/
|
|
174
|
+
router.get('/', async (c) => {
|
|
175
|
+
try {
|
|
176
|
+
const projectId = c.req.query('projectId');
|
|
177
|
+
// Validate projectId is provided
|
|
178
|
+
if (!projectId) {
|
|
179
|
+
const errorResponse = {
|
|
180
|
+
error: {
|
|
181
|
+
code: 'INVALID_REQUEST',
|
|
182
|
+
message: 'projectId query parameter is required',
|
|
183
|
+
timestamp: new Date().toISOString()
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
return c.json(errorResponse, 400);
|
|
187
|
+
}
|
|
188
|
+
const threads = await threadManager.listThreads(projectId);
|
|
189
|
+
return c.json(threads);
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
const errorResponse = {
|
|
193
|
+
error: {
|
|
194
|
+
code: 'LIST_THREADS_ERROR',
|
|
195
|
+
message: 'Failed to list threads',
|
|
196
|
+
details: error instanceof Error ? error.message : String(error),
|
|
197
|
+
timestamp: new Date().toISOString()
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
return c.json(errorResponse, 500);
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
/**
|
|
204
|
+
* DELETE /api/threads/:id
|
|
205
|
+
* Delete a thread
|
|
206
|
+
*
|
|
207
|
+
* Response:
|
|
208
|
+
* {
|
|
209
|
+
* "success": true,
|
|
210
|
+
* "message": "Thread deleted successfully"
|
|
211
|
+
* }
|
|
212
|
+
*
|
|
213
|
+
* Requirements:
|
|
214
|
+
* - 6.3 - THE CLI SHALL expose REST API endpoints for Thread operations
|
|
215
|
+
* - 8.4 - WHEN deleting a Thread, THE App SHALL send a DELETE request with the Thread identifier to the CLI
|
|
216
|
+
*/
|
|
217
|
+
router.delete('/:id', async (c) => {
|
|
218
|
+
try {
|
|
219
|
+
const threadId = c.req.param('id');
|
|
220
|
+
if (!threadId) {
|
|
221
|
+
const errorResponse = {
|
|
222
|
+
error: {
|
|
223
|
+
code: 'INVALID_REQUEST',
|
|
224
|
+
message: 'Thread ID is required',
|
|
225
|
+
timestamp: new Date().toISOString()
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
return c.json(errorResponse, 400);
|
|
229
|
+
}
|
|
230
|
+
await threadManager.deleteThread(threadId);
|
|
231
|
+
return c.json({
|
|
232
|
+
success: true,
|
|
233
|
+
message: 'Thread deleted successfully'
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
238
|
+
// Check if it's a "not found" error
|
|
239
|
+
if (errorMessage.includes('not found')) {
|
|
240
|
+
const errorResponse = {
|
|
241
|
+
error: {
|
|
242
|
+
code: 'THREAD_NOT_FOUND',
|
|
243
|
+
message: errorMessage,
|
|
244
|
+
timestamp: new Date().toISOString()
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
return c.json(errorResponse, 404);
|
|
248
|
+
}
|
|
249
|
+
const errorResponse = {
|
|
250
|
+
error: {
|
|
251
|
+
code: 'DELETE_THREAD_ERROR',
|
|
252
|
+
message: 'Failed to delete thread',
|
|
253
|
+
details: errorMessage,
|
|
254
|
+
timestamp: new Date().toISOString()
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
return c.json(errorResponse, 500);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
/**
|
|
261
|
+
* POST /api/threads/:id/select
|
|
262
|
+
* Select a thread as the active thread
|
|
263
|
+
*
|
|
264
|
+
* Response:
|
|
265
|
+
* {
|
|
266
|
+
* "success": true,
|
|
267
|
+
* "message": "Thread selected successfully",
|
|
268
|
+
* "threadId": "uuid"
|
|
269
|
+
* }
|
|
270
|
+
*
|
|
271
|
+
* Requirements:
|
|
272
|
+
* - 6.3 - THE CLI SHALL expose REST API endpoints for Thread operations
|
|
273
|
+
*/
|
|
274
|
+
router.post('/:id/select', async (c) => {
|
|
275
|
+
try {
|
|
276
|
+
const threadId = c.req.param('id');
|
|
277
|
+
if (!threadId) {
|
|
278
|
+
const errorResponse = {
|
|
279
|
+
error: {
|
|
280
|
+
code: 'INVALID_REQUEST',
|
|
281
|
+
message: 'Thread ID is required',
|
|
282
|
+
timestamp: new Date().toISOString()
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
return c.json(errorResponse, 400);
|
|
286
|
+
}
|
|
287
|
+
// Verify thread exists
|
|
288
|
+
const thread = await threadManager.getThread(threadId);
|
|
289
|
+
if (!thread) {
|
|
290
|
+
const errorResponse = {
|
|
291
|
+
error: {
|
|
292
|
+
code: 'THREAD_NOT_FOUND',
|
|
293
|
+
message: `Thread not found: ${threadId}`,
|
|
294
|
+
timestamp: new Date().toISOString()
|
|
295
|
+
}
|
|
296
|
+
};
|
|
297
|
+
return c.json(errorResponse, 404);
|
|
298
|
+
}
|
|
299
|
+
await threadManager.selectThread(threadId);
|
|
300
|
+
return c.json({
|
|
301
|
+
success: true,
|
|
302
|
+
message: 'Thread selected successfully',
|
|
303
|
+
threadId
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
catch (error) {
|
|
307
|
+
const errorResponse = {
|
|
308
|
+
error: {
|
|
309
|
+
code: 'SELECT_THREAD_ERROR',
|
|
310
|
+
message: 'Failed to select thread',
|
|
311
|
+
details: error instanceof Error ? error.message : String(error),
|
|
312
|
+
timestamp: new Date().toISOString()
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
return c.json(errorResponse, 500);
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
/**
|
|
319
|
+
* GET /api/threads/:id/messages
|
|
320
|
+
* Get chat history for a thread
|
|
321
|
+
*/
|
|
322
|
+
router.get('/:id/messages', async (c) => {
|
|
323
|
+
try {
|
|
324
|
+
const threadId = c.req.param('id');
|
|
325
|
+
if (!threadId) {
|
|
326
|
+
const errorResponse = {
|
|
327
|
+
error: {
|
|
328
|
+
code: 'INVALID_REQUEST',
|
|
329
|
+
message: 'Thread ID is required',
|
|
330
|
+
timestamp: new Date().toISOString()
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
return c.json(errorResponse, 400);
|
|
334
|
+
}
|
|
335
|
+
const thread = await threadManager.getThread(threadId);
|
|
336
|
+
if (!thread) {
|
|
337
|
+
const errorResponse = {
|
|
338
|
+
error: {
|
|
339
|
+
code: 'THREAD_NOT_FOUND',
|
|
340
|
+
message: `Thread not found: ${threadId}`,
|
|
341
|
+
timestamp: new Date().toISOString()
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
return c.json(errorResponse, 404);
|
|
345
|
+
}
|
|
346
|
+
const history = await conversationManager.getConversationHistory(thread.path);
|
|
347
|
+
if (!history || history.messages.length === 0) {
|
|
348
|
+
return c.json([]);
|
|
349
|
+
}
|
|
350
|
+
const messages = history.messages.flatMap((message) => {
|
|
351
|
+
const userMessage = {
|
|
352
|
+
messageId: `user-${message.id}`,
|
|
353
|
+
sender: 'user',
|
|
354
|
+
content: message.request.message,
|
|
355
|
+
contentType: 'text',
|
|
356
|
+
timestamp: message.timestamp,
|
|
357
|
+
model: message.request.model,
|
|
358
|
+
attachments: message.request.attachments?.map((attachment) => ({
|
|
359
|
+
fileName: attachment.name,
|
|
360
|
+
content: attachment.content,
|
|
361
|
+
size: attachment.size,
|
|
362
|
+
}))
|
|
363
|
+
};
|
|
364
|
+
if (!message.response) {
|
|
365
|
+
return [userMessage];
|
|
366
|
+
}
|
|
367
|
+
const agentMessage = {
|
|
368
|
+
messageId: `agent-${message.id}`,
|
|
369
|
+
sender: 'agent',
|
|
370
|
+
content: extractAssistantContent(message.response.events, message.response.content),
|
|
371
|
+
contentType: 'markdown',
|
|
372
|
+
timestamp: message.response.completedAt,
|
|
373
|
+
model: message.request.model,
|
|
374
|
+
};
|
|
375
|
+
return [userMessage, agentMessage];
|
|
376
|
+
});
|
|
377
|
+
return c.json(messages);
|
|
378
|
+
}
|
|
379
|
+
catch (error) {
|
|
380
|
+
const errorResponse = {
|
|
381
|
+
error: {
|
|
382
|
+
code: 'GET_THREAD_MESSAGES_ERROR',
|
|
383
|
+
message: 'Failed to load thread messages',
|
|
384
|
+
details: error instanceof Error ? error.message : String(error),
|
|
385
|
+
timestamp: new Date().toISOString()
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
return c.json(errorResponse, 500);
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
return router;
|
|
392
|
+
}
|
|
393
|
+
//# sourceMappingURL=threads-old.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thread routes for the REST API
|
|
3
|
+
*
|
|
4
|
+
* Handles all thread-related operations:
|
|
5
|
+
* - POST /api/threads - Create a new thread
|
|
6
|
+
* - GET /api/threads?projectId=xxx - List threads for a project
|
|
7
|
+
* - DELETE /api/threads/:id - Delete a thread
|
|
8
|
+
*/
|
|
9
|
+
import { Hono } from 'hono';
|
|
10
|
+
import type { ThreadManager } from '../managers/thread-manager.js';
|
|
11
|
+
import type { ConversationManager } from '../managers/conversation-manager.js';
|
|
12
|
+
import type { GitManager } from '../managers/git-manager.js';
|
|
13
|
+
export declare function createThreadRoutes(threadManager: ThreadManager, gitManager: GitManager, conversationManager: ConversationManager): Hono;
|
|
14
|
+
//# sourceMappingURL=threads.d.ts.map
|