@relaycast/engine 4.1.6 → 5.0.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/dist/adapters/node/index.d.ts.map +1 -1
- package/dist/adapters/node/index.js +23 -1
- package/dist/adapters/node/index.js.map +1 -1
- package/dist/adapters/node/presence.d.ts +7 -3
- package/dist/adapters/node/presence.d.ts.map +1 -1
- package/dist/adapters/node/presence.js +10 -8
- package/dist/adapters/node/presence.js.map +1 -1
- package/dist/adapters/node/realtime.d.ts.map +1 -1
- package/dist/adapters/node/realtime.js +8 -3
- package/dist/adapters/node/realtime.js.map +1 -1
- package/dist/bin/serve.js +2 -4
- package/dist/bin/serve.js.map +1 -1
- package/dist/db/migrations/0021_node_delivery_contracts.sql +70 -0
- package/dist/db/migrations/0022_http_push_redrive.sql +13 -0
- package/dist/db/migrations/0023_direct_ws_nodes.sql +124 -0
- package/dist/db/migrations/0024_binding_workspace_constraints.sql +109 -0
- package/dist/db/schema.d.ts +339 -0
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +48 -1
- package/dist/db/schema.js.map +1 -1
- package/dist/engine/action.d.ts +0 -7
- package/dist/engine/action.d.ts.map +1 -1
- package/dist/engine/action.js +0 -7
- package/dist/engine/action.js.map +1 -1
- package/dist/engine/agent.d.ts.map +1 -1
- package/dist/engine/agent.js +7 -1
- package/dist/engine/agent.js.map +1 -1
- package/dist/engine/delivery.d.ts +24 -0
- package/dist/engine/delivery.d.ts.map +1 -1
- package/dist/engine/delivery.js +190 -74
- package/dist/engine/delivery.js.map +1 -1
- package/dist/engine/deliveryWrites.d.ts +5 -0
- package/dist/engine/deliveryWrites.d.ts.map +1 -1
- package/dist/engine/deliveryWrites.js +51 -11
- package/dist/engine/deliveryWrites.js.map +1 -1
- package/dist/engine/invocationCompletion.d.ts +1 -1
- package/dist/engine/invocationCompletion.d.ts.map +1 -1
- package/dist/engine/invocationCompletion.js +1 -16
- package/dist/engine/invocationCompletion.js.map +1 -1
- package/dist/engine/message.d.ts.map +1 -1
- package/dist/engine/message.js +1 -0
- package/dist/engine/message.js.map +1 -1
- package/dist/engine/node.d.ts +85 -0
- package/dist/engine/node.d.ts.map +1 -1
- package/dist/engine/node.js +473 -14
- package/dist/engine/node.js.map +1 -1
- package/dist/engine/nodeContext.d.ts +22 -0
- package/dist/engine/nodeContext.d.ts.map +1 -0
- package/dist/engine/nodeContext.js +104 -0
- package/dist/engine/nodeContext.js.map +1 -0
- package/dist/engine/thread.d.ts.map +1 -1
- package/dist/engine/thread.js +37 -17
- package/dist/engine/thread.js.map +1 -1
- package/dist/engine/wsAuth.d.ts +36 -0
- package/dist/engine/wsAuth.d.ts.map +1 -0
- package/dist/engine/wsAuth.js +57 -0
- package/dist/engine/wsAuth.js.map +1 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +46 -74
- package/dist/engine.js.map +1 -1
- package/dist/entrypoints/node.d.ts.map +1 -1
- package/dist/entrypoints/node.js +27 -51
- package/dist/entrypoints/node.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/httpError.d.ts +5 -1
- package/dist/lib/httpError.d.ts.map +1 -1
- package/dist/lib/httpError.js +9 -5
- package/dist/lib/httpError.js.map +1 -1
- package/dist/lib/httpQuery.d.ts +28 -0
- package/dist/lib/httpQuery.d.ts.map +1 -0
- package/dist/lib/httpQuery.js +32 -0
- package/dist/lib/httpQuery.js.map +1 -0
- package/dist/lib/httpResponse.d.ts +116 -0
- package/dist/lib/httpResponse.d.ts.map +1 -0
- package/dist/lib/httpResponse.js +65 -0
- package/dist/lib/httpResponse.js.map +1 -0
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +3 -2
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/idempotency.d.ts +30 -0
- package/dist/middleware/idempotency.d.ts.map +1 -1
- package/dist/middleware/idempotency.js +14 -0
- package/dist/middleware/idempotency.js.map +1 -1
- package/dist/middleware/planLimits.d.ts.map +1 -1
- package/dist/middleware/planLimits.js +2 -7
- package/dist/middleware/planLimits.js.map +1 -1
- package/dist/middleware/rateLimit.d.ts.map +1 -1
- package/dist/middleware/rateLimit.js +2 -7
- package/dist/middleware/rateLimit.js.map +1 -1
- package/dist/ports/index.d.ts +0 -14
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/routes/a2a.d.ts.map +1 -1
- package/dist/routes/a2a.js +41 -83
- package/dist/routes/a2a.js.map +1 -1
- package/dist/routes/action.d.ts.map +1 -1
- package/dist/routes/action.js +32 -37
- package/dist/routes/action.js.map +1 -1
- package/dist/routes/agent.d.ts.map +1 -1
- package/dist/routes/agent.js +69 -73
- package/dist/routes/agent.js.map +1 -1
- package/dist/routes/certify.d.ts.map +1 -1
- package/dist/routes/certify.js +21 -35
- package/dist/routes/certify.js.map +1 -1
- package/dist/routes/channel.d.ts.map +1 -1
- package/dist/routes/channel.js +33 -71
- package/dist/routes/channel.js.map +1 -1
- package/dist/routes/console.d.ts.map +1 -1
- package/dist/routes/console.js +22 -32
- package/dist/routes/console.js.map +1 -1
- package/dist/routes/delivery.d.ts.map +1 -1
- package/dist/routes/delivery.js +22 -54
- package/dist/routes/delivery.js.map +1 -1
- package/dist/routes/deliveryRouting.d.ts +6 -0
- package/dist/routes/deliveryRouting.d.ts.map +1 -1
- package/dist/routes/deliveryRouting.js +289 -35
- package/dist/routes/deliveryRouting.js.map +1 -1
- package/dist/routes/directory.d.ts.map +1 -1
- package/dist/routes/directory.js +47 -63
- package/dist/routes/directory.js.map +1 -1
- package/dist/routes/dm.d.ts.map +1 -1
- package/dist/routes/dm.js +21 -42
- package/dist/routes/dm.js.map +1 -1
- package/dist/routes/eventSubscription.d.ts.map +1 -1
- package/dist/routes/eventSubscription.js +15 -21
- package/dist/routes/eventSubscription.js.map +1 -1
- package/dist/routes/fanout.d.ts +2 -1
- package/dist/routes/fanout.d.ts.map +1 -1
- package/dist/routes/fanout.js +25 -15
- package/dist/routes/fanout.js.map +1 -1
- package/dist/routes/file.d.ts.map +1 -1
- package/dist/routes/file.js +34 -40
- package/dist/routes/file.js.map +1 -1
- package/dist/routes/groupDm.d.ts.map +1 -1
- package/dist/routes/groupDm.js +23 -48
- package/dist/routes/groupDm.js.map +1 -1
- package/dist/routes/inboundWebhook.d.ts.map +1 -1
- package/dist/routes/inboundWebhook.js +17 -35
- package/dist/routes/inboundWebhook.js.map +1 -1
- package/dist/routes/inbox.d.ts.map +1 -1
- package/dist/routes/inbox.js +2 -1
- package/dist/routes/inbox.js.map +1 -1
- package/dist/routes/message.d.ts.map +1 -1
- package/dist/routes/message.js +39 -50
- package/dist/routes/message.js.map +1 -1
- package/dist/routes/node.d.ts.map +1 -1
- package/dist/routes/node.js +125 -12
- package/dist/routes/node.js.map +1 -1
- package/dist/routes/presence.d.ts.map +1 -1
- package/dist/routes/presence.js +4 -3
- package/dist/routes/presence.js.map +1 -1
- package/dist/routes/reaction.d.ts.map +1 -1
- package/dist/routes/reaction.js +10 -21
- package/dist/routes/reaction.js.map +1 -1
- package/dist/routes/receipt.d.ts.map +1 -1
- package/dist/routes/receipt.js +7 -15
- package/dist/routes/receipt.js.map +1 -1
- package/dist/routes/routing.d.ts.map +1 -1
- package/dist/routes/routing.js +38 -51
- package/dist/routes/routing.js.map +1 -1
- package/dist/routes/search.d.ts.map +1 -1
- package/dist/routes/search.js +15 -12
- package/dist/routes/search.js.map +1 -1
- package/dist/routes/systemPrompt.d.ts.map +1 -1
- package/dist/routes/systemPrompt.js +8 -13
- package/dist/routes/systemPrompt.js.map +1 -1
- package/dist/routes/thread.d.ts.map +1 -1
- package/dist/routes/thread.js +17 -35
- package/dist/routes/thread.js.map +1 -1
- package/dist/routes/trigger.d.ts.map +1 -1
- package/dist/routes/trigger.js +15 -14
- package/dist/routes/trigger.js.map +1 -1
- package/dist/routes/workspace.d.ts.map +1 -1
- package/dist/routes/workspace.js +39 -220
- package/dist/routes/workspace.js.map +1 -1
- package/package.json +3 -3
- package/dist/lib/fleetNodes.d.ts +0 -9
- package/dist/lib/fleetNodes.d.ts.map +0 -1
- package/dist/lib/fleetNodes.js +0 -66
- package/dist/lib/fleetNodes.js.map +0 -1
- package/dist/lib/workspaceStream.d.ts +0 -9
- package/dist/lib/workspaceStream.d.ts.map +0 -1
- package/dist/lib/workspaceStream.js +0 -53
- package/dist/lib/workspaceStream.js.map +0 -1
- package/dist/middleware/fleetNodes.d.ts +0 -10
- package/dist/middleware/fleetNodes.d.ts.map +0 -1
- package/dist/middleware/fleetNodes.js +0 -18
- package/dist/middleware/fleetNodes.js.map +0 -1
package/dist/routes/thread.js
CHANGED
|
@@ -2,16 +2,18 @@ import { Hono } from 'hono';
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { requireAuth } from '../middleware/auth.js';
|
|
4
4
|
import { rateLimit } from '../middleware/rateLimit.js';
|
|
5
|
-
import { parseIdempotencyKey, runIdempotent } from '../middleware/idempotency.js';
|
|
5
|
+
import { jsonIdempotentOk, parseIdempotencyKey, runIdempotent } from '../middleware/idempotency.js';
|
|
6
6
|
import * as threadEngine from '../engine/thread.js';
|
|
7
7
|
import { resolveMailboxConfig } from '../engine/mailboxConfig.js';
|
|
8
|
-
import {
|
|
8
|
+
import { publishWorkspaceEvent } from './fanout.js';
|
|
9
9
|
import { notifyDeliveryRejections, routeDeliveryOutcomes } from './deliveryRouting.js';
|
|
10
10
|
import { buildThreadReplyEventData } from '../engine/deliveryWire.js';
|
|
11
11
|
import { runInBackground } from './background.js';
|
|
12
12
|
import { sendWebhookEvent } from './webhookOutbox.js';
|
|
13
13
|
import { emitServerEvent } from '../lib/serverTelemetry.js';
|
|
14
14
|
import { errorResponse } from '../lib/httpError.js';
|
|
15
|
+
import { jsonError, jsonOk, parseJsonBody } from '../lib/httpResponse.js';
|
|
16
|
+
import { parsePaginationQuery } from '../lib/httpQuery.js';
|
|
15
17
|
export const threadRoutes = new Hono();
|
|
16
18
|
const postReplySchema = z.object({
|
|
17
19
|
text: z.string().min(1),
|
|
@@ -24,27 +26,18 @@ threadRoutes.post('/messages/:id/replies', requireAuth, rateLimit, async (c) =>
|
|
|
24
26
|
const db = c.get('db');
|
|
25
27
|
const workspace = c.get('workspace');
|
|
26
28
|
const agent = c.get('agent');
|
|
27
|
-
const parsed =
|
|
28
|
-
if (!parsed.
|
|
29
|
-
return
|
|
30
|
-
ok: false,
|
|
31
|
-
error: { code: 'invalid_request', message: 'text is required' },
|
|
32
|
-
}, 400);
|
|
29
|
+
const parsed = await parseJsonBody(c, postReplySchema, 'invalid reply body');
|
|
30
|
+
if (!parsed.ok) {
|
|
31
|
+
return parsed.response;
|
|
33
32
|
}
|
|
34
33
|
const { text, blocks, data } = parsed.data;
|
|
35
34
|
const { key: idempotencyKey, error: idempotencyError } = parseIdempotencyKey(c.req.header('Idempotency-Key'));
|
|
36
35
|
if (idempotencyError) {
|
|
37
|
-
return c
|
|
38
|
-
ok: false,
|
|
39
|
-
error: { code: 'invalid_idempotency_key', message: idempotencyError },
|
|
40
|
-
}, 400);
|
|
36
|
+
return jsonError(c, 'invalid_idempotency_key', idempotencyError, 400);
|
|
41
37
|
}
|
|
42
38
|
const agentId = agent?.id;
|
|
43
39
|
if (!agentId) {
|
|
44
|
-
return c
|
|
45
|
-
ok: false,
|
|
46
|
-
error: { code: 'agent_token_required', message: 'Agent token required to post replies' },
|
|
47
|
-
}, 403);
|
|
40
|
+
return jsonError(c, 'agent_token_required', 'Agent token required to post replies', 403);
|
|
48
41
|
}
|
|
49
42
|
const parentId = c.req.param('id');
|
|
50
43
|
const mailbox = resolveMailboxConfig(c.get('engine').config, workspace.id);
|
|
@@ -69,23 +62,11 @@ threadRoutes.post('/messages/:id/replies', requireAuth, rateLimit, async (c) =>
|
|
|
69
62
|
});
|
|
70
63
|
},
|
|
71
64
|
});
|
|
72
|
-
if (idempotent.replayed) {
|
|
73
|
-
c.header('Idempotency-Replayed', 'true');
|
|
74
|
-
}
|
|
75
65
|
if (!idempotent.replayed) {
|
|
76
66
|
const { _deliveries, _delivery_rejections, ...publicReplyData } = idempotent.data;
|
|
77
67
|
const eventData = toThreadReplyEventData(idempotent.data);
|
|
78
68
|
if (publicReplyData.channel_id) {
|
|
79
|
-
|
|
80
|
-
runInBackground(c, (async () => {
|
|
81
|
-
const dmAgentIds = await getDmParticipantAgentIds(c, channelId);
|
|
82
|
-
if (dmAgentIds) {
|
|
83
|
-
await fanoutToAgents(c, dmAgentIds, 'thread.reply', eventData);
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
await fanoutToChannel(c, channelId, 'thread.reply', eventData);
|
|
87
|
-
}
|
|
88
|
-
})(), 'fanout thread.reply');
|
|
69
|
+
runInBackground(c, publishWorkspaceEvent(c, 'thread.reply', eventData, publicReplyData.channel_id), 'publish thread.reply');
|
|
89
70
|
}
|
|
90
71
|
if (_deliveries && _deliveries.length > 0) {
|
|
91
72
|
runInBackground(c, routeDeliveryOutcomes(c, _deliveries, 'thread.reply', eventData), 'route thread deliveries');
|
|
@@ -99,8 +80,7 @@ threadRoutes.post('/messages/:id/replies', requireAuth, rateLimit, async (c) =>
|
|
|
99
80
|
channel_id: publicReplyData.channel_id ?? null,
|
|
100
81
|
});
|
|
101
82
|
}
|
|
102
|
-
|
|
103
|
-
return c.json({ ok: true, data: responseData }, idempotent.status);
|
|
83
|
+
return jsonIdempotentOk(c, idempotent);
|
|
104
84
|
}
|
|
105
85
|
catch (err) {
|
|
106
86
|
return errorResponse(c, err);
|
|
@@ -111,12 +91,14 @@ threadRoutes.get('/messages/:id/replies', requireAuth, rateLimit, async (c) => {
|
|
|
111
91
|
try {
|
|
112
92
|
const db = c.get('db');
|
|
113
93
|
const workspace = c.get('workspace');
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
94
|
+
const query = parsePaginationQuery(c);
|
|
95
|
+
if (!query.ok) {
|
|
96
|
+
return query.response;
|
|
97
|
+
}
|
|
98
|
+
const { limit, before, after } = query.data;
|
|
117
99
|
const parentId = c.req.param('id');
|
|
118
100
|
const result = await threadEngine.getThread(db, workspace.id, parentId, { limit, before, after });
|
|
119
|
-
return c
|
|
101
|
+
return jsonOk(c, result);
|
|
120
102
|
}
|
|
121
103
|
catch (err) {
|
|
122
104
|
return errorResponse(c, err);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"thread.js","sourceRoot":"","sources":["../../src/routes/thread.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"thread.js","sourceRoot":"","sources":["../../src/routes/thread.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trigger.d.ts","sourceRoot":"","sources":["../../src/routes/trigger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"trigger.d.ts","sourceRoot":"","sources":["../../src/routes/trigger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAaxC,eAAO,MAAM,aAAa,qDAAqB,CAAC"}
|
package/dist/routes/trigger.js
CHANGED
|
@@ -3,6 +3,7 @@ import { z } from 'zod';
|
|
|
3
3
|
import { requireAuth } from '../middleware/auth.js';
|
|
4
4
|
import { rateLimit } from '../middleware/rateLimit.js';
|
|
5
5
|
import { errorResponse } from '../lib/httpError.js';
|
|
6
|
+
import { jsonCreated, jsonNoContent, jsonNotFound, jsonOk, parseJsonBody, } from '../lib/httpResponse.js';
|
|
6
7
|
import * as triggerEngine from '../engine/trigger.js';
|
|
7
8
|
export const triggerRoutes = new Hono();
|
|
8
9
|
const triggerBodySchema = z.object({
|
|
@@ -16,12 +17,12 @@ const updateTriggerBodySchema = triggerBodySchema.partial();
|
|
|
16
17
|
// POST /v1/triggers
|
|
17
18
|
triggerRoutes.post('/triggers', requireAuth, rateLimit, async (c) => {
|
|
18
19
|
try {
|
|
19
|
-
const parsed =
|
|
20
|
-
if (!parsed.
|
|
21
|
-
return
|
|
20
|
+
const parsed = await parseJsonBody(c, triggerBodySchema, 'invalid trigger body');
|
|
21
|
+
if (!parsed.ok) {
|
|
22
|
+
return parsed.response;
|
|
22
23
|
}
|
|
23
24
|
const result = await triggerEngine.createTrigger(c.get('db'), c.get('workspace').id, parsed.data);
|
|
24
|
-
return c
|
|
25
|
+
return jsonCreated(c, result);
|
|
25
26
|
}
|
|
26
27
|
catch (err) {
|
|
27
28
|
return errorResponse(c, err);
|
|
@@ -31,7 +32,7 @@ triggerRoutes.post('/triggers', requireAuth, rateLimit, async (c) => {
|
|
|
31
32
|
triggerRoutes.get('/triggers', requireAuth, rateLimit, async (c) => {
|
|
32
33
|
try {
|
|
33
34
|
const result = await triggerEngine.listTriggers(c.get('db'), c.get('workspace').id);
|
|
34
|
-
return c
|
|
35
|
+
return jsonOk(c, result);
|
|
35
36
|
}
|
|
36
37
|
catch (err) {
|
|
37
38
|
return errorResponse(c, err);
|
|
@@ -42,9 +43,9 @@ triggerRoutes.get('/triggers/:id', requireAuth, rateLimit, async (c) => {
|
|
|
42
43
|
try {
|
|
43
44
|
const result = await triggerEngine.getTrigger(c.get('db'), c.get('workspace').id, c.req.param('id'));
|
|
44
45
|
if (!result) {
|
|
45
|
-
return c
|
|
46
|
+
return jsonNotFound(c, 'trigger_not_found', 'Trigger not found');
|
|
46
47
|
}
|
|
47
|
-
return c
|
|
48
|
+
return jsonOk(c, result);
|
|
48
49
|
}
|
|
49
50
|
catch (err) {
|
|
50
51
|
return errorResponse(c, err);
|
|
@@ -53,15 +54,15 @@ triggerRoutes.get('/triggers/:id', requireAuth, rateLimit, async (c) => {
|
|
|
53
54
|
// PATCH /v1/triggers/:id
|
|
54
55
|
triggerRoutes.patch('/triggers/:id', requireAuth, rateLimit, async (c) => {
|
|
55
56
|
try {
|
|
56
|
-
const parsed =
|
|
57
|
-
if (!parsed.
|
|
58
|
-
return
|
|
57
|
+
const parsed = await parseJsonBody(c, updateTriggerBodySchema, 'invalid trigger body');
|
|
58
|
+
if (!parsed.ok) {
|
|
59
|
+
return parsed.response;
|
|
59
60
|
}
|
|
60
61
|
const result = await triggerEngine.updateTrigger(c.get('db'), c.get('workspace').id, c.req.param('id'), parsed.data);
|
|
61
62
|
if (!result) {
|
|
62
|
-
return c
|
|
63
|
+
return jsonNotFound(c, 'trigger_not_found', 'Trigger not found');
|
|
63
64
|
}
|
|
64
|
-
return c
|
|
65
|
+
return jsonOk(c, result);
|
|
65
66
|
}
|
|
66
67
|
catch (err) {
|
|
67
68
|
return errorResponse(c, err);
|
|
@@ -72,9 +73,9 @@ triggerRoutes.delete('/triggers/:id', requireAuth, rateLimit, async (c) => {
|
|
|
72
73
|
try {
|
|
73
74
|
const deleted = await triggerEngine.deleteTrigger(c.get('db'), c.get('workspace').id, c.req.param('id'));
|
|
74
75
|
if (!deleted) {
|
|
75
|
-
return c
|
|
76
|
+
return jsonNotFound(c, 'trigger_not_found', 'Trigger not found');
|
|
76
77
|
}
|
|
77
|
-
return c
|
|
78
|
+
return jsonNoContent(c);
|
|
78
79
|
}
|
|
79
80
|
catch (err) {
|
|
80
81
|
return errorResponse(c, err);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trigger.js","sourceRoot":"","sources":["../../src/routes/trigger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AAEtD,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,IAAI,EAAU,CAAC;AAEhD,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACzC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACzC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC1C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAC;AAEH,MAAM,uBAAuB,GAAG,iBAAiB,CAAC,OAAO,EAAE,CAAC;AAE5D,oBAAoB;AACpB,aAAa,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;IAClE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,
|
|
1
|
+
{"version":3,"file":"trigger.js","sourceRoot":"","sources":["../../src/routes/trigger.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/routes/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/routes/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAoBxC,eAAO,MAAM,eAAe,qDAAqB,CAAC"}
|
package/dist/routes/workspace.js
CHANGED
|
@@ -7,11 +7,10 @@ import * as workspaceEngine from '../engine/workspace.js';
|
|
|
7
7
|
import * as activityEngine from '../engine/activity.js';
|
|
8
8
|
import * as dmAllEngine from '../engine/dmAll.js';
|
|
9
9
|
import * as tokenRotateEngine from '../engine/tokenRotate.js';
|
|
10
|
-
import { getWorkspaceStreamConfig, setWorkspaceStreamOverride, } from '../lib/workspaceStream.js';
|
|
11
|
-
import { getFleetNodesConfig, setFleetNodesOverride, } from '../lib/fleetNodes.js';
|
|
12
|
-
import { getRequestLogger, toErrorDetails } from '../lib/logger.js';
|
|
13
10
|
import { emitServerEvent } from '../lib/serverTelemetry.js';
|
|
14
|
-
import { errorResponse
|
|
11
|
+
import { errorResponse } from '../lib/httpError.js';
|
|
12
|
+
import { jsonCreated, jsonError, jsonNoContent, jsonNotFound, jsonOk, parseJsonBody, parseQueryParams, } from '../lib/httpResponse.js';
|
|
13
|
+
import { parsePaginationQuery, positiveIntQueryParam } from '../lib/httpQuery.js';
|
|
15
14
|
export const workspaceRoutes = new Hono();
|
|
16
15
|
const createWorkspaceSchema = z.object({
|
|
17
16
|
name: z.string().min(1),
|
|
@@ -20,14 +19,12 @@ const updateWorkspaceSchema = z.object({
|
|
|
20
19
|
name: z.string().optional(),
|
|
21
20
|
system_prompt: z.string().nullable().optional(),
|
|
22
21
|
});
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
mode: z.string().optional(),
|
|
30
|
-
}).passthrough();
|
|
22
|
+
const activityQuerySchema = z.object({
|
|
23
|
+
limit: positiveIntQueryParam({ defaultValue: 20, max: 500 }),
|
|
24
|
+
});
|
|
25
|
+
function workspaceNotFound(c) {
|
|
26
|
+
return jsonNotFound(c, 'workspace_not_found', 'Workspace not found');
|
|
27
|
+
}
|
|
31
28
|
const PUBLIC_WORKSPACE_LOOKUP_LIMIT = 30;
|
|
32
29
|
const publicWorkspaceLookupBuckets = new Map();
|
|
33
30
|
let lastPublicWorkspaceLookupCleanup = Date.now();
|
|
@@ -80,13 +77,7 @@ const publicWorkspaceLookupRateLimit = createMiddleware(async (c, next) => {
|
|
|
80
77
|
c.header('X-RateLimit-Limit', String(limit));
|
|
81
78
|
c.header('X-RateLimit-Remaining', String(remaining));
|
|
82
79
|
if (!allowed) {
|
|
83
|
-
return c.
|
|
84
|
-
ok: false,
|
|
85
|
-
error: {
|
|
86
|
-
code: 'rate_limit_exceeded',
|
|
87
|
-
message: `Rate limit exceeded. ${limit} requests per minute allowed for public workspace lookups.`,
|
|
88
|
-
},
|
|
89
|
-
}, 429);
|
|
80
|
+
return jsonError(c, 'rate_limit_exceeded', `Rate limit exceeded. ${limit} requests per minute allowed for public workspace lookups.`, 429);
|
|
90
81
|
}
|
|
91
82
|
}
|
|
92
83
|
catch {
|
|
@@ -94,13 +85,7 @@ const publicWorkspaceLookupRateLimit = createMiddleware(async (c, next) => {
|
|
|
94
85
|
c.header('X-RateLimit-Limit', String(limit));
|
|
95
86
|
c.header('X-RateLimit-Remaining', String(remaining));
|
|
96
87
|
if (!allowed) {
|
|
97
|
-
return c.
|
|
98
|
-
ok: false,
|
|
99
|
-
error: {
|
|
100
|
-
code: 'rate_limit_exceeded',
|
|
101
|
-
message: `Rate limit exceeded. ${limit} requests per minute allowed for public workspace lookups.`,
|
|
102
|
-
},
|
|
103
|
-
}, 429);
|
|
88
|
+
return jsonError(c, 'rate_limit_exceeded', `Rate limit exceeded. ${limit} requests per minute allowed for public workspace lookups.`, 429);
|
|
104
89
|
}
|
|
105
90
|
}
|
|
106
91
|
await next();
|
|
@@ -108,9 +93,9 @@ const publicWorkspaceLookupRateLimit = createMiddleware(async (c, next) => {
|
|
|
108
93
|
// POST /workspaces - create workspace (no auth required, workspace key optional)
|
|
109
94
|
workspaceRoutes.post('/workspaces', async (c) => {
|
|
110
95
|
try {
|
|
111
|
-
const parsed =
|
|
112
|
-
if (!parsed.
|
|
113
|
-
return
|
|
96
|
+
const parsed = await parseJsonBody(c, createWorkspaceSchema, 'name is required');
|
|
97
|
+
if (!parsed.ok) {
|
|
98
|
+
return parsed.response;
|
|
114
99
|
}
|
|
115
100
|
const { name } = parsed.data;
|
|
116
101
|
const db = c.get('db');
|
|
@@ -121,7 +106,7 @@ workspaceRoutes.post('/workspaces', async (c) => {
|
|
|
121
106
|
created_via: 'api',
|
|
122
107
|
});
|
|
123
108
|
}
|
|
124
|
-
return
|
|
109
|
+
return result.created ? jsonCreated(c, result.workspace) : jsonOk(c, result.workspace);
|
|
125
110
|
}
|
|
126
111
|
catch (err) {
|
|
127
112
|
return errorResponse(c, err);
|
|
@@ -133,9 +118,9 @@ workspaceRoutes.get('/workspaces/by-name/:name', publicWorkspaceLookupRateLimit,
|
|
|
133
118
|
const db = c.get('db');
|
|
134
119
|
const workspace = await workspaceEngine.getWorkspaceByName(db, c.req.param('name'));
|
|
135
120
|
if (!workspace) {
|
|
136
|
-
return c
|
|
121
|
+
return workspaceNotFound(c);
|
|
137
122
|
}
|
|
138
|
-
return c
|
|
123
|
+
return jsonOk(c, workspace);
|
|
139
124
|
}
|
|
140
125
|
catch (err) {
|
|
141
126
|
return errorResponse(c, err);
|
|
@@ -147,9 +132,9 @@ workspaceRoutes.get('/workspace', requireWorkspaceKey, rateLimit, async (c) => {
|
|
|
147
132
|
const db = c.get('db');
|
|
148
133
|
const workspace = await workspaceEngine.getWorkspace(db, c.get('workspace').id);
|
|
149
134
|
if (!workspace) {
|
|
150
|
-
return c
|
|
135
|
+
return workspaceNotFound(c);
|
|
151
136
|
}
|
|
152
|
-
return c
|
|
137
|
+
return jsonOk(c, workspace);
|
|
153
138
|
}
|
|
154
139
|
catch (err) {
|
|
155
140
|
return errorResponse(c, err);
|
|
@@ -160,20 +145,20 @@ workspaceRoutes.patch('/workspace', requireWorkspaceKey, rateLimit, async (c) =>
|
|
|
160
145
|
try {
|
|
161
146
|
const db = c.get('db');
|
|
162
147
|
const workspace = c.get('workspace');
|
|
163
|
-
const parsed =
|
|
164
|
-
if (!parsed.
|
|
165
|
-
return
|
|
148
|
+
const parsed = await parseJsonBody(c, updateWorkspaceSchema, 'invalid workspace update body');
|
|
149
|
+
if (!parsed.ok) {
|
|
150
|
+
return parsed.response;
|
|
166
151
|
}
|
|
167
152
|
const body = parsed.data;
|
|
168
153
|
const updated = await workspaceEngine.updateWorkspace(db, workspace.id, body);
|
|
169
154
|
if (!updated) {
|
|
170
|
-
return c
|
|
155
|
+
return workspaceNotFound(c);
|
|
171
156
|
}
|
|
172
157
|
emitServerEvent(c, workspace.id, 'relaycast_server_workspace_updated', {
|
|
173
158
|
changed_name: typeof body?.name === 'string',
|
|
174
159
|
changed_system_prompt: typeof body?.system_prompt === 'string',
|
|
175
160
|
});
|
|
176
|
-
return c
|
|
161
|
+
return jsonOk(c, updated);
|
|
177
162
|
}
|
|
178
163
|
catch (err) {
|
|
179
164
|
return errorResponse(c, err);
|
|
@@ -188,7 +173,7 @@ workspaceRoutes.delete('/workspace', requireWorkspaceKey, rateLimit, async (c) =
|
|
|
188
173
|
emitServerEvent(c, workspace.id, 'relaycast_server_workspace_deleted', {
|
|
189
174
|
deleted_via: 'api',
|
|
190
175
|
});
|
|
191
|
-
return c
|
|
176
|
+
return jsonNoContent(c);
|
|
192
177
|
}
|
|
193
178
|
catch (err) {
|
|
194
179
|
return errorResponse(c, err);
|
|
@@ -199,10 +184,13 @@ workspaceRoutes.get('/activity', requireWorkspaceKey, rateLimit, async (c) => {
|
|
|
199
184
|
try {
|
|
200
185
|
const db = c.get('db');
|
|
201
186
|
const workspace = c.get('workspace');
|
|
202
|
-
const
|
|
203
|
-
|
|
187
|
+
const parsed = parseQueryParams(c, activityQuerySchema, 'Invalid activity query');
|
|
188
|
+
if (!parsed.ok) {
|
|
189
|
+
return parsed.response;
|
|
190
|
+
}
|
|
191
|
+
const { limit } = parsed.data;
|
|
204
192
|
const items = await activityEngine.getActivityFeed(db, workspace.id, limit);
|
|
205
|
-
return c
|
|
193
|
+
return jsonOk(c, items);
|
|
206
194
|
}
|
|
207
195
|
catch (err) {
|
|
208
196
|
return errorResponse(c, err);
|
|
@@ -214,7 +202,7 @@ workspaceRoutes.get('/dm/conversations/all', requireWorkspaceKey, rateLimit, asy
|
|
|
214
202
|
const db = c.get('db');
|
|
215
203
|
const workspace = c.get('workspace');
|
|
216
204
|
const conversations = await dmAllEngine.listAllDmConversations(db, workspace.id);
|
|
217
|
-
return c
|
|
205
|
+
return jsonOk(c, conversations);
|
|
218
206
|
}
|
|
219
207
|
catch (err) {
|
|
220
208
|
return errorResponse(c, err);
|
|
@@ -226,12 +214,13 @@ workspaceRoutes.get('/dm/conversations/:conversation_id/messages', requireWorksp
|
|
|
226
214
|
const db = c.get('db');
|
|
227
215
|
const workspace = c.get('workspace');
|
|
228
216
|
const conversationId = c.req.param('conversation_id');
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
217
|
+
const query = parsePaginationQuery(c);
|
|
218
|
+
if (!query.ok) {
|
|
219
|
+
return query.response;
|
|
220
|
+
}
|
|
221
|
+
const { limit, before, after } = query.data;
|
|
233
222
|
const msgs = await dmAllEngine.getDmMessagesForWorkspace(db, workspace.id, conversationId, { limit, before, after });
|
|
234
|
-
return c
|
|
223
|
+
return jsonOk(c, msgs);
|
|
235
224
|
}
|
|
236
225
|
catch (err) {
|
|
237
226
|
return errorResponse(c, err);
|
|
@@ -246,180 +235,10 @@ workspaceRoutes.post('/agents/:name/rotate-token', requireWorkspaceKey, rateLimi
|
|
|
246
235
|
emitServerEvent(c, workspace.id, 'relaycast_server_agent_token_rotated', {
|
|
247
236
|
agent_name: c.req.param('name'),
|
|
248
237
|
});
|
|
249
|
-
return c
|
|
238
|
+
return jsonOk(c, result);
|
|
250
239
|
}
|
|
251
240
|
catch (err) {
|
|
252
241
|
return errorResponse(c, err);
|
|
253
242
|
}
|
|
254
243
|
});
|
|
255
|
-
// GET /workspace/stream - get workspace stream effective config
|
|
256
|
-
workspaceRoutes.get('/workspace/stream', requireWorkspaceKey, rateLimit, async (c) => {
|
|
257
|
-
const logger = getRequestLogger(c, 'workspace.stream.get');
|
|
258
|
-
const workspaceId = c.get('workspace').id;
|
|
259
|
-
try {
|
|
260
|
-
const { kv, config: engineConfig } = c.get('engine');
|
|
261
|
-
const config = await getWorkspaceStreamConfig(kv, workspaceId, engineConfig.workspaceStreamEnabled ?? false);
|
|
262
|
-
return c.json({
|
|
263
|
-
ok: true,
|
|
264
|
-
data: {
|
|
265
|
-
enabled: config.enabled,
|
|
266
|
-
default_enabled: config.defaultEnabled,
|
|
267
|
-
override: config.override,
|
|
268
|
-
},
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
catch (err) {
|
|
272
|
-
const error = asCodedError(err);
|
|
273
|
-
logger.error('Failed to get stream config', {
|
|
274
|
-
workspaceId,
|
|
275
|
-
code: error.code,
|
|
276
|
-
status: error.status,
|
|
277
|
-
...toErrorDetails(error),
|
|
278
|
-
});
|
|
279
|
-
return c.json({
|
|
280
|
-
ok: false,
|
|
281
|
-
error: { code: error.code || 'internal_error', message: error.message },
|
|
282
|
-
}, (error.status || 500));
|
|
283
|
-
}
|
|
284
|
-
});
|
|
285
|
-
// PUT /workspace/stream - set workspace stream override
|
|
286
|
-
workspaceRoutes.put('/workspace/stream', requireWorkspaceKey, rateLimit, async (c) => {
|
|
287
|
-
const logger = getRequestLogger(c, 'workspace.stream.put');
|
|
288
|
-
const workspaceId = c.get('workspace').id;
|
|
289
|
-
try {
|
|
290
|
-
const parsed = updateWorkspaceStreamSchema.safeParse(await c.req.json());
|
|
291
|
-
if (!parsed.success) {
|
|
292
|
-
return c.json({
|
|
293
|
-
ok: false,
|
|
294
|
-
error: { code: 'invalid_request', message: 'Provide { enabled: boolean } or { mode: "inherit" }' },
|
|
295
|
-
}, 400);
|
|
296
|
-
}
|
|
297
|
-
const body = parsed.data;
|
|
298
|
-
let override;
|
|
299
|
-
if (body?.mode === 'inherit') {
|
|
300
|
-
override = null;
|
|
301
|
-
}
|
|
302
|
-
else if (typeof body?.enabled === 'boolean') {
|
|
303
|
-
override = body.enabled;
|
|
304
|
-
}
|
|
305
|
-
else {
|
|
306
|
-
return c.json({
|
|
307
|
-
ok: false,
|
|
308
|
-
error: { code: 'invalid_request', message: 'Provide { enabled: boolean } or { mode: "inherit" }' },
|
|
309
|
-
}, 400);
|
|
310
|
-
}
|
|
311
|
-
const { kv, config: engineConfig } = c.get('engine');
|
|
312
|
-
await setWorkspaceStreamOverride(kv, workspaceId, override);
|
|
313
|
-
const config = await getWorkspaceStreamConfig(kv, workspaceId, engineConfig.workspaceStreamEnabled ?? false);
|
|
314
|
-
emitServerEvent(c, workspaceId, 'relaycast_server_workspace_stream_updated', {
|
|
315
|
-
stream_mode: override === null ? 'inherit' : (override ? 'enabled' : 'disabled'),
|
|
316
|
-
});
|
|
317
|
-
return c.json({
|
|
318
|
-
ok: true,
|
|
319
|
-
data: {
|
|
320
|
-
enabled: config.enabled,
|
|
321
|
-
default_enabled: config.defaultEnabled,
|
|
322
|
-
override: config.override,
|
|
323
|
-
},
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
catch (err) {
|
|
327
|
-
const error = asCodedError(err);
|
|
328
|
-
logger.error('Failed to update stream config', {
|
|
329
|
-
workspaceId,
|
|
330
|
-
code: error.code,
|
|
331
|
-
status: error.status,
|
|
332
|
-
...toErrorDetails(error),
|
|
333
|
-
});
|
|
334
|
-
return c.json({
|
|
335
|
-
ok: false,
|
|
336
|
-
error: { code: error.code || 'internal_error', message: error.message },
|
|
337
|
-
}, (error.status || 500));
|
|
338
|
-
}
|
|
339
|
-
});
|
|
340
|
-
// GET /workspace/fleet-nodes - effective fleet node control rollout flag (Phase 6)
|
|
341
|
-
workspaceRoutes.get('/workspace/fleet-nodes', requireWorkspaceKey, rateLimit, async (c) => {
|
|
342
|
-
const logger = getRequestLogger(c, 'workspace.fleet_nodes.get');
|
|
343
|
-
const workspaceId = c.get('workspace').id;
|
|
344
|
-
try {
|
|
345
|
-
const { kv, config: engineConfig } = c.get('engine');
|
|
346
|
-
const config = await getFleetNodesConfig(kv, workspaceId, engineConfig.fleetNodesEnabled ?? false);
|
|
347
|
-
return c.json({
|
|
348
|
-
ok: true,
|
|
349
|
-
data: {
|
|
350
|
-
enabled: config.enabled,
|
|
351
|
-
default_enabled: config.defaultEnabled,
|
|
352
|
-
override: config.override,
|
|
353
|
-
},
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
catch (err) {
|
|
357
|
-
const error = asCodedError(err);
|
|
358
|
-
logger.error('Failed to get fleet nodes config', {
|
|
359
|
-
workspaceId,
|
|
360
|
-
code: error.code,
|
|
361
|
-
status: error.status,
|
|
362
|
-
...toErrorDetails(error),
|
|
363
|
-
});
|
|
364
|
-
return c.json({
|
|
365
|
-
ok: false,
|
|
366
|
-
error: { code: error.code || 'internal_error', message: error.message },
|
|
367
|
-
}, (error.status || 500));
|
|
368
|
-
}
|
|
369
|
-
});
|
|
370
|
-
// PUT /workspace/fleet-nodes - set the per-workspace fleet node control override
|
|
371
|
-
workspaceRoutes.put('/workspace/fleet-nodes', requireWorkspaceKey, rateLimit, async (c) => {
|
|
372
|
-
const logger = getRequestLogger(c, 'workspace.fleet_nodes.put');
|
|
373
|
-
const workspaceId = c.get('workspace').id;
|
|
374
|
-
try {
|
|
375
|
-
const parsed = updateFleetNodesSchema.safeParse(await c.req.json());
|
|
376
|
-
if (!parsed.success) {
|
|
377
|
-
return c.json({
|
|
378
|
-
ok: false,
|
|
379
|
-
error: { code: 'invalid_request', message: 'Provide { enabled: boolean } or { mode: "inherit" }' },
|
|
380
|
-
}, 400);
|
|
381
|
-
}
|
|
382
|
-
const body = parsed.data;
|
|
383
|
-
let override;
|
|
384
|
-
if (body?.mode === 'inherit') {
|
|
385
|
-
override = null;
|
|
386
|
-
}
|
|
387
|
-
else if (typeof body?.enabled === 'boolean') {
|
|
388
|
-
override = body.enabled;
|
|
389
|
-
}
|
|
390
|
-
else {
|
|
391
|
-
return c.json({
|
|
392
|
-
ok: false,
|
|
393
|
-
error: { code: 'invalid_request', message: 'Provide { enabled: boolean } or { mode: "inherit" }' },
|
|
394
|
-
}, 400);
|
|
395
|
-
}
|
|
396
|
-
const { kv, config: engineConfig } = c.get('engine');
|
|
397
|
-
await setFleetNodesOverride(kv, workspaceId, override);
|
|
398
|
-
const config = await getFleetNodesConfig(kv, workspaceId, engineConfig.fleetNodesEnabled ?? false);
|
|
399
|
-
emitServerEvent(c, workspaceId, 'relaycast_server_workspace_fleet_nodes_updated', {
|
|
400
|
-
fleet_nodes_mode: override === null ? 'inherit' : (override ? 'enabled' : 'disabled'),
|
|
401
|
-
});
|
|
402
|
-
return c.json({
|
|
403
|
-
ok: true,
|
|
404
|
-
data: {
|
|
405
|
-
enabled: config.enabled,
|
|
406
|
-
default_enabled: config.defaultEnabled,
|
|
407
|
-
override: config.override,
|
|
408
|
-
},
|
|
409
|
-
});
|
|
410
|
-
}
|
|
411
|
-
catch (err) {
|
|
412
|
-
const error = asCodedError(err);
|
|
413
|
-
logger.error('Failed to update fleet nodes config', {
|
|
414
|
-
workspaceId,
|
|
415
|
-
code: error.code,
|
|
416
|
-
status: error.status,
|
|
417
|
-
...toErrorDetails(error),
|
|
418
|
-
});
|
|
419
|
-
return c.json({
|
|
420
|
-
ok: false,
|
|
421
|
-
error: { code: error.code || 'internal_error', message: error.message },
|
|
422
|
-
}, (error.status || 500));
|
|
423
|
-
}
|
|
424
|
-
});
|
|
425
244
|
//# sourceMappingURL=workspace.js.map
|