@nordbyte/nordrelay 0.5.0 → 0.5.1

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 (38) hide show
  1. package/README.md +16 -10
  2. package/dist/access-control.js +2 -0
  3. package/dist/agent-updates.js +43 -8
  4. package/dist/bot-ui.js +1 -0
  5. package/dist/bot.js +108 -1063
  6. package/dist/channel-actions.js +8 -8
  7. package/dist/operations.js +63 -9
  8. package/dist/relay-artifact-service.js +126 -0
  9. package/dist/relay-external-activity-monitor.js +216 -0
  10. package/dist/relay-queue-service.js +66 -0
  11. package/dist/relay-runtime-types.js +1 -0
  12. package/dist/relay-runtime.js +77 -359
  13. package/dist/support-bundle.js +205 -0
  14. package/dist/telegram-agent-commands.js +212 -0
  15. package/dist/telegram-artifact-commands.js +139 -0
  16. package/dist/telegram-command-menu.js +1 -0
  17. package/dist/telegram-command-types.js +1 -0
  18. package/dist/telegram-diagnostics-command.js +102 -0
  19. package/dist/telegram-general-commands.js +52 -0
  20. package/dist/telegram-operational-commands.js +153 -0
  21. package/dist/telegram-preference-commands.js +198 -0
  22. package/dist/telegram-queue-commands.js +278 -0
  23. package/dist/telegram-support-command.js +53 -0
  24. package/dist/telegram-update-commands.js +6 -1
  25. package/dist/web-api-contract.js +79 -31
  26. package/dist/web-api-types.js +1 -0
  27. package/dist/web-dashboard-access-routes.js +163 -0
  28. package/dist/web-dashboard-artifact-routes.js +65 -0
  29. package/dist/web-dashboard-assets.js +2 -0
  30. package/dist/web-dashboard-http.js +143 -0
  31. package/dist/web-dashboard-pages.js +257 -0
  32. package/dist/web-dashboard-runtime-routes.js +92 -0
  33. package/dist/web-dashboard-session-routes.js +209 -0
  34. package/dist/web-dashboard.js +43 -882
  35. package/dist/webui-assets/dashboard.css +74 -4
  36. package/dist/webui-assets/dashboard.js +163 -24
  37. package/dist/zip-writer.js +83 -0
  38. package/package.json +10 -4
@@ -0,0 +1,209 @@
1
+ import { isAgentId } from "./agent.js";
2
+ import { numberParam, optionalBooleanField, optionalStringField, parseUploadFiles, readJsonBody, requiredSearch, sendJson, stringField, } from "./web-dashboard-http.js";
3
+ export async function handleDashboardSessionRoute(req, res, url, options) {
4
+ const { runtime, authUser } = options;
5
+ if (req.method === "GET" && url.pathname === "/api/locks") {
6
+ await options.assertCurrentSessionScope(authUser);
7
+ sendJson(res, 200, { locks: runtime.locks() });
8
+ return true;
9
+ }
10
+ if (req.method === "POST" && url.pathname === "/api/locks") {
11
+ const body = await readJsonBody(req);
12
+ await options.assertCurrentSessionScope(authUser);
13
+ sendJson(res, 200, { lock: runtime.lockWebSession(optionalStringField(body, "ownerName")), locks: runtime.locks() });
14
+ return true;
15
+ }
16
+ if (req.method === "DELETE" && url.pathname === "/api/locks") {
17
+ await options.assertCurrentSessionScope(authUser);
18
+ sendJson(res, 200, runtime.unlockWebSession());
19
+ return true;
20
+ }
21
+ if (req.method === "GET" && url.pathname === "/api/auth/status") {
22
+ const agentId = options.parseAgentId(url.searchParams.get("agent") ?? undefined);
23
+ options.assertScopedAgent(authUser, agentId);
24
+ sendJson(res, 200, await runtime.authStatus(agentId));
25
+ return true;
26
+ }
27
+ if (req.method === "POST" && url.pathname === "/api/auth/login") {
28
+ const body = await readJsonBody(req);
29
+ const agentId = options.parseAgentId(optionalStringField(body, "agentId"));
30
+ options.assertScopedAgent(authUser, agentId);
31
+ sendJson(res, 200, await runtime.login(agentId));
32
+ return true;
33
+ }
34
+ if (req.method === "POST" && url.pathname === "/api/auth/logout") {
35
+ const body = await readJsonBody(req);
36
+ const agentId = options.parseAgentId(optionalStringField(body, "agentId"));
37
+ options.assertScopedAgent(authUser, agentId);
38
+ sendJson(res, 200, await runtime.logout(agentId));
39
+ return true;
40
+ }
41
+ if (req.method === "GET" && url.pathname === "/api/snapshot") {
42
+ await options.assertCurrentSessionScope(authUser);
43
+ sendJson(res, 200, await runtime.snapshot());
44
+ return true;
45
+ }
46
+ if (req.method === "GET" && url.pathname === "/api/sessions") {
47
+ const agentId = options.parseAgentId(url.searchParams.get("agent") ?? undefined);
48
+ if (agentId) {
49
+ options.assertScopedAgent(authUser, agentId);
50
+ }
51
+ else {
52
+ await options.assertCurrentSessionScope(authUser);
53
+ }
54
+ const page = await runtime.listSessionsPage(numberParam(url, "page", 1), numberParam(url, "limit", 50), url.searchParams.get("query") ?? "", agentId);
55
+ sendJson(res, 200, options.scopedSessionPage(authUser, page));
56
+ return true;
57
+ }
58
+ if (req.method === "POST" && url.pathname === "/api/agent") {
59
+ const body = await readJsonBody(req);
60
+ const agentId = stringField(body, "agentId");
61
+ if (!isAgentId(agentId)) {
62
+ throw new Error(`Invalid agent: ${agentId}`);
63
+ }
64
+ options.assertScopedAgent(authUser, agentId);
65
+ sendJson(res, 200, { session: await runtime.setAgent(agentId) });
66
+ return true;
67
+ }
68
+ if (req.method === "POST" && url.pathname === "/api/sessions/new") {
69
+ const body = await readJsonBody(req);
70
+ const agentId = options.parseAgentId(optionalStringField(body, "agentId"));
71
+ const workspace = optionalStringField(body, "workspace");
72
+ options.assertScopedAgent(authUser, agentId);
73
+ options.assertScopedWorkspace(authUser, workspace);
74
+ sendJson(res, 200, {
75
+ session: await runtime.newSession({
76
+ agentId,
77
+ workspace,
78
+ model: optionalStringField(body, "model"),
79
+ reasoningEffort: optionalStringField(body, "reasoningEffort"),
80
+ launchProfileId: optionalStringField(body, "launchProfileId"),
81
+ fastMode: optionalBooleanField(body, "fastMode"),
82
+ }),
83
+ });
84
+ return true;
85
+ }
86
+ if (req.method === "POST" && url.pathname === "/api/sessions/switch") {
87
+ const body = await readJsonBody(req);
88
+ const threadId = stringField(body, "threadId");
89
+ const detail = await runtime.sessionDetail(threadId);
90
+ if (detail.record && typeof detail.record === "object") {
91
+ options.assertSessionScope(authUser, detail.record);
92
+ }
93
+ const session = await runtime.switchSession(threadId);
94
+ options.assertSessionScope(authUser, session);
95
+ sendJson(res, 200, { session });
96
+ return true;
97
+ }
98
+ if (req.method === "POST" && url.pathname === "/api/sessions/attach") {
99
+ const body = await readJsonBody(req);
100
+ const session = await runtime.attachSession(stringField(body, "threadId"));
101
+ options.assertSessionScope(authUser, session);
102
+ sendJson(res, 200, { session });
103
+ return true;
104
+ }
105
+ if (req.method === "GET" && url.pathname === "/api/sessions/detail") {
106
+ const threadId = requiredSearch(url, "threadId");
107
+ const detail = await runtime.sessionDetail(threadId);
108
+ options.assertSessionDetailScope(authUser, threadId, detail);
109
+ sendJson(res, 200, detail);
110
+ return true;
111
+ }
112
+ if (req.method === "GET" && url.pathname === "/api/models") {
113
+ await options.assertCurrentSessionScope(authUser);
114
+ sendJson(res, 200, { models: await runtime.listModels() });
115
+ return true;
116
+ }
117
+ if (req.method === "POST" && url.pathname === "/api/session/model") {
118
+ const body = await readJsonBody(req);
119
+ await options.assertCurrentSessionScope(authUser);
120
+ sendJson(res, 200, { session: await runtime.setModel(stringField(body, "model")) });
121
+ return true;
122
+ }
123
+ if (req.method === "POST" && url.pathname === "/api/session/reasoning") {
124
+ const body = await readJsonBody(req);
125
+ await options.assertCurrentSessionScope(authUser);
126
+ sendJson(res, 200, { session: await runtime.setReasoningEffort(stringField(body, "reasoning")) });
127
+ return true;
128
+ }
129
+ if (req.method === "POST" && url.pathname === "/api/session/fast") {
130
+ const body = await readJsonBody(req);
131
+ await options.assertCurrentSessionScope(authUser);
132
+ sendJson(res, 200, { session: await runtime.setFastMode(Boolean(body?.enabled)) });
133
+ return true;
134
+ }
135
+ if (req.method === "POST" && url.pathname === "/api/session/launch") {
136
+ const body = await readJsonBody(req);
137
+ await options.assertCurrentSessionScope(authUser);
138
+ sendJson(res, 200, { session: await runtime.setLaunchProfile(stringField(body, "profileId")) });
139
+ return true;
140
+ }
141
+ if (req.method === "POST" && url.pathname === "/api/prompt") {
142
+ const body = await readJsonBody(req);
143
+ await options.assertCurrentSessionScope(authUser);
144
+ sendJson(res, 202, await runtime.sendPrompt(stringField(body, "text")));
145
+ return true;
146
+ }
147
+ if (req.method === "POST" && url.pathname === "/api/prompt/upload") {
148
+ const body = await readJsonBody(req);
149
+ await options.assertCurrentSessionScope(authUser);
150
+ sendJson(res, 202, await runtime.sendUploadPrompt({
151
+ text: optionalStringField(body, "text"),
152
+ files: parseUploadFiles(body.files),
153
+ }));
154
+ return true;
155
+ }
156
+ if (req.method === "POST" && (url.pathname === "/api/abort" || url.pathname === "/api/stop")) {
157
+ await options.assertCurrentSessionScope(authUser);
158
+ await runtime.abort();
159
+ sendJson(res, 200, { ok: true });
160
+ return true;
161
+ }
162
+ if (req.method === "POST" && url.pathname === "/api/handback") {
163
+ await options.assertCurrentSessionScope(authUser);
164
+ sendJson(res, 200, await runtime.handback());
165
+ return true;
166
+ }
167
+ if (req.method === "POST" && url.pathname === "/api/retry") {
168
+ await options.assertCurrentSessionScope(authUser);
169
+ sendJson(res, 202, await runtime.retry());
170
+ return true;
171
+ }
172
+ if (req.method === "POST" && url.pathname === "/api/sync") {
173
+ await options.assertCurrentSessionScope(authUser);
174
+ sendJson(res, 200, await runtime.sync());
175
+ return true;
176
+ }
177
+ if (req.method === "GET" && url.pathname === "/api/queue") {
178
+ await options.assertCurrentSessionScope(authUser);
179
+ sendJson(res, 200, { queue: runtime.queue(), paused: runtime.queuePaused() });
180
+ return true;
181
+ }
182
+ if (req.method === "POST" && url.pathname === "/api/queue") {
183
+ const body = await readJsonBody(req);
184
+ await options.assertCurrentSessionScope(authUser);
185
+ sendJson(res, 200, { queue: runtime.queueAction(stringField(body, "action"), optionalStringField(body, "id")), paused: runtime.queuePaused() });
186
+ return true;
187
+ }
188
+ if (req.method === "GET" && url.pathname === "/api/chat/history") {
189
+ await options.assertCurrentSessionScope(authUser);
190
+ sendJson(res, 200, { messages: await runtime.chatHistory(numberParam(url, "limit", 200)) });
191
+ return true;
192
+ }
193
+ if (req.method === "DELETE" && url.pathname === "/api/chat/history") {
194
+ await options.assertCurrentSessionScope(authUser);
195
+ sendJson(res, 200, await runtime.clearChatHistory());
196
+ return true;
197
+ }
198
+ if (req.method === "GET" && url.pathname === "/api/activity") {
199
+ sendJson(res, 200, {
200
+ events: options.filterActivityByScope(authUser, runtime.activity({
201
+ limit: numberParam(url, "limit", 100),
202
+ source: (url.searchParams.get("source") || "all"),
203
+ status: (url.searchParams.get("status") || "all"),
204
+ })),
205
+ });
206
+ return true;
207
+ }
208
+ return false;
209
+ }