agentgui 1.0.838 → 1.0.839
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/CHANGELOG.md +2 -0
- package/lib/routes-agent-actions.js +117 -0
- package/lib/routes-auth-config.js +30 -0
- package/lib/routes-messages.js +139 -0
- package/lib/routes-runs.js +156 -0
- package/lib/routes-scripts.js +135 -0
- package/lib/routes-sessions.js +144 -0
- package/package.json +1 -1
- package/server.js +24 -1032
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
export function register(deps) {
|
|
2
|
+
const { queries, sendJSON, activeExecutions, rateLimitState, debugLog } = deps;
|
|
3
|
+
|
|
4
|
+
const routes = {};
|
|
5
|
+
|
|
6
|
+
routes['_match'] = (method, pathOnly) => {
|
|
7
|
+
let m;
|
|
8
|
+
|
|
9
|
+
if (method === 'GET' && (m = pathOnly.match(/^\/api\/conversations\/([^/]+)\/messages\/([^/]+)$/)))
|
|
10
|
+
return (req, res) => handleGetMessage(req, res, m[1], m[2]);
|
|
11
|
+
|
|
12
|
+
if (method === 'GET' && (m = pathOnly.match(/^\/api\/sessions\/([^/]+)$/)))
|
|
13
|
+
return (req, res) => handleGetSession(req, res, m[1]);
|
|
14
|
+
|
|
15
|
+
if (method === 'GET' && (m = pathOnly.match(/^\/api\/conversations\/([^/]+)\/full$/)))
|
|
16
|
+
return (req, res) => handleFullLoad(req, res, m[1]);
|
|
17
|
+
|
|
18
|
+
if (method === 'GET' && (m = pathOnly.match(/^\/api\/conversations\/([^/]+)\/chunks$/)))
|
|
19
|
+
return (req, res) => handleConvChunks(req, res, m[1]);
|
|
20
|
+
|
|
21
|
+
if (method === 'GET' && (m = pathOnly.match(/^\/api\/sessions\/([^/]+)\/chunks$/)))
|
|
22
|
+
return (req, res) => handleSessionChunks(req, res, m[1]);
|
|
23
|
+
|
|
24
|
+
if (method === 'GET' && (m = pathOnly.match(/^\/api\/conversations\/([^/]+)\/sessions\/latest$/)))
|
|
25
|
+
return (req, res) => handleLatestSession(req, res, m[1]);
|
|
26
|
+
|
|
27
|
+
if (method === 'GET' && (m = pathOnly.match(/^\/api\/sessions\/([^/]+)\/execution$/)))
|
|
28
|
+
return (req, res) => handleExecution(req, res, m[1]);
|
|
29
|
+
|
|
30
|
+
return null;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
async function handleGetMessage(req, res, conversationId, msgId) {
|
|
34
|
+
const msg = queries.getMessage(msgId);
|
|
35
|
+
if (!msg || msg.conversationId !== conversationId) { sendJSON(req, res, 404, { error: 'Not found' }); return; }
|
|
36
|
+
sendJSON(req, res, 200, { message: msg });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function handleGetSession(req, res, sessionId) {
|
|
40
|
+
const sess = queries.getSession(sessionId);
|
|
41
|
+
if (!sess) { sendJSON(req, res, 404, { error: 'Not found' }); return; }
|
|
42
|
+
const events = queries.getSessionEvents(sessionId);
|
|
43
|
+
sendJSON(req, res, 200, { session: sess, events });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function handleFullLoad(req, res, conversationId) {
|
|
47
|
+
const conv = queries.getConversation(conversationId);
|
|
48
|
+
if (!conv) { sendJSON(req, res, 404, { error: 'Not found' }); return; }
|
|
49
|
+
const latestSession = queries.getLatestSession(conversationId);
|
|
50
|
+
const isActivelyStreaming = activeExecutions.has(conversationId);
|
|
51
|
+
const url = new URL(req.url, 'http://localhost');
|
|
52
|
+
const chunkLimit = Math.min(parseInt(url.searchParams.get('chunkLimit') || '500'), 5000);
|
|
53
|
+
const allChunks = url.searchParams.get('allChunks') === '1';
|
|
54
|
+
const totalChunks = queries.getConversationChunkCount(conversationId);
|
|
55
|
+
let chunks;
|
|
56
|
+
if (allChunks || totalChunks <= chunkLimit) {
|
|
57
|
+
chunks = queries.getConversationChunks(conversationId);
|
|
58
|
+
} else {
|
|
59
|
+
chunks = queries.getRecentConversationChunks(conversationId, chunkLimit);
|
|
60
|
+
}
|
|
61
|
+
const msgResult = queries.getPaginatedMessages(conversationId, 100, 0);
|
|
62
|
+
const rateLimitInfo = rateLimitState.get(conversationId) || null;
|
|
63
|
+
sendJSON(req, res, 200, {
|
|
64
|
+
conversation: conv,
|
|
65
|
+
isActivelyStreaming,
|
|
66
|
+
latestSession,
|
|
67
|
+
chunks,
|
|
68
|
+
totalChunks,
|
|
69
|
+
messages: msgResult.messages,
|
|
70
|
+
rateLimitInfo
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async function handleConvChunks(req, res, conversationId) {
|
|
75
|
+
const conv = queries.getConversation(conversationId);
|
|
76
|
+
if (!conv) { sendJSON(req, res, 404, { error: 'Conversation not found' }); return; }
|
|
77
|
+
const url = new URL(req.url, 'http://localhost');
|
|
78
|
+
const since = parseInt(url.searchParams.get('since') || '0');
|
|
79
|
+
const all = url.searchParams.get('all') === 'true';
|
|
80
|
+
const totalChunks = queries.getConversationChunkCount(conversationId);
|
|
81
|
+
let chunks;
|
|
82
|
+
if (since > 0) {
|
|
83
|
+
chunks = queries.getConversationChunksSince(conversationId, since);
|
|
84
|
+
} else if (all) {
|
|
85
|
+
chunks = queries.getConversationChunks(conversationId);
|
|
86
|
+
} else {
|
|
87
|
+
chunks = queries.getRecentConversationChunks(conversationId, 500);
|
|
88
|
+
}
|
|
89
|
+
debugLog(`[chunks] Conv ${conversationId}: ${chunks.length} chunks (total: ${totalChunks})`);
|
|
90
|
+
sendJSON(req, res, 200, { ok: true, chunks, totalChunks });
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function handleSessionChunks(req, res, sessionId) {
|
|
94
|
+
const sess = queries.getSession(sessionId);
|
|
95
|
+
if (!sess) { sendJSON(req, res, 404, { error: 'Session not found' }); return; }
|
|
96
|
+
const url = new URL(req.url, 'http://localhost');
|
|
97
|
+
const sinceSeq = parseInt(url.searchParams.get('sinceSeq') || '-1');
|
|
98
|
+
const since = parseInt(url.searchParams.get('since') || '0');
|
|
99
|
+
let chunks;
|
|
100
|
+
if (sinceSeq >= 0) {
|
|
101
|
+
chunks = queries.getChunksSinceSeq(sessionId, sinceSeq);
|
|
102
|
+
} else {
|
|
103
|
+
chunks = queries.getChunksSince(sessionId, since);
|
|
104
|
+
}
|
|
105
|
+
sendJSON(req, res, 200, { ok: true, chunks });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function handleLatestSession(req, res, convId) {
|
|
109
|
+
const latestSession = queries.getLatestSession(convId);
|
|
110
|
+
if (!latestSession) { sendJSON(req, res, 200, { session: null }); return; }
|
|
111
|
+
const events = queries.getSessionEvents(latestSession.id);
|
|
112
|
+
sendJSON(req, res, 200, { session: latestSession, events });
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async function handleExecution(req, res, sessionId) {
|
|
116
|
+
const url = new URL(req.url, 'http://localhost');
|
|
117
|
+
const limit = Math.min(parseInt(url.searchParams.get('limit') || '1000'), 5000);
|
|
118
|
+
const offset = Math.max(parseInt(url.searchParams.get('offset') || '0'), 0);
|
|
119
|
+
const filterType = url.searchParams.get('filterType');
|
|
120
|
+
try {
|
|
121
|
+
const session = queries.getSession(sessionId);
|
|
122
|
+
const allChunks = session ? (queries.getChunksSince(sessionId, 0) || []) : [];
|
|
123
|
+
const filtered = filterType ? allChunks.filter(e => e.type === filterType) : allChunks;
|
|
124
|
+
sendJSON(req, res, 200, {
|
|
125
|
+
sessionId,
|
|
126
|
+
events: filtered.slice(offset, offset + limit),
|
|
127
|
+
total: filtered.length,
|
|
128
|
+
limit,
|
|
129
|
+
offset,
|
|
130
|
+
hasMore: offset + limit < filtered.length,
|
|
131
|
+
metadata: {
|
|
132
|
+
status: session?.status || 'unknown',
|
|
133
|
+
startTime: session?.created_at || null,
|
|
134
|
+
duration: session?.completed_at && session?.created_at ? session.completed_at - session.created_at : 0,
|
|
135
|
+
eventCount: filtered.length
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
} catch (err) {
|
|
139
|
+
sendJSON(req, res, 400, { error: err.message });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return routes;
|
|
144
|
+
}
|