agent-relay-server 0.32.1 → 0.32.3
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/docs/openapi.json +57 -127
- package/package.json +1 -1
- package/public/assets/{activity-C6nbfryG.js → activity-DT1JGHnp.js} +2 -2
- package/public/assets/{activity-C6nbfryG.js.map → activity-DT1JGHnp.js.map} +1 -1
- package/public/assets/{agent-profiles-FEITAgHs.js → agent-profiles-CrMemMkZ.js} +2 -2
- package/public/assets/{agent-profiles-FEITAgHs.js.map → agent-profiles-CrMemMkZ.js.map} +1 -1
- package/public/assets/{agents-D4S0yIbe.js → agents-Bl-rrgOy.js} +2 -2
- package/public/assets/{agents-D4S0yIbe.js.map → agents-Bl-rrgOy.js.map} +1 -1
- package/public/assets/{analytics-DM2g62T_.js → analytics-a663ak56.js} +2 -2
- package/public/assets/{analytics-DM2g62T_.js.map → analytics-a663ak56.js.map} +1 -1
- package/public/assets/{automation-3D2pQa1C.js → automation-CiaLThdO.js} +2 -2
- package/public/assets/{automation-3D2pQa1C.js.map → automation-CiaLThdO.js.map} +1 -1
- package/public/assets/{branch-state-badge-Bi4IbkOZ.js → branch-state-badge-D4ur3m3_.js} +2 -2
- package/public/assets/{branch-state-badge-Bi4IbkOZ.js.map → branch-state-badge-D4ur3m3_.js.map} +1 -1
- package/public/assets/{channels-QNp7zmA_.js → channels-o9KLTHoK.js} +2 -2
- package/public/assets/{channels-QNp7zmA_.js.map → channels-o9KLTHoK.js.map} +1 -1
- package/public/assets/{chat-jeXt_SFs.js → chat-5hvHZcAe.js} +2 -2
- package/public/assets/{chat-jeXt_SFs.js.map → chat-5hvHZcAe.js.map} +1 -1
- package/public/assets/{connectors-BGJARDui.js → connectors-CdC806mA.js} +2 -2
- package/public/assets/{connectors-BGJARDui.js.map → connectors-CdC806mA.js.map} +1 -1
- package/public/assets/{formatted-body-impl-B7FgqkYL.js → formatted-body-impl-Ca74OAEH.js} +2 -2
- package/public/assets/{formatted-body-impl-B7FgqkYL.js.map → formatted-body-impl-Ca74OAEH.js.map} +1 -1
- package/public/assets/{index-2m9mT8kV.js → index-C_33ymaw.js} +6 -6
- package/public/assets/{index-2m9mT8kV.js.map → index-C_33ymaw.js.map} +1 -1
- package/public/assets/{integrations-CJm8-FcG.js → integrations-1nxMizDY.js} +2 -2
- package/public/assets/{integrations-CJm8-FcG.js.map → integrations-1nxMizDY.js.map} +1 -1
- package/public/assets/{maintenance-CBvZrVAG.js → maintenance-DiFNzNPN.js} +2 -2
- package/public/assets/{maintenance-CBvZrVAG.js.map → maintenance-DiFNzNPN.js.map} +1 -1
- package/public/assets/{managed-agents-Dcmm8YKt.js → managed-agents-Do3dKvfj.js} +2 -2
- package/public/assets/{managed-agents-Dcmm8YKt.js.map → managed-agents-Do3dKvfj.js.map} +1 -1
- package/public/assets/{markdown-preview-impl-7xjqdiEu.js → markdown-preview-impl-CLA0J255.js} +2 -2
- package/public/assets/{markdown-preview-impl-7xjqdiEu.js.map → markdown-preview-impl-CLA0J255.js.map} +1 -1
- package/public/assets/{memory-BmGNW61h.js → memory-IjwqFzBd.js} +2 -2
- package/public/assets/{memory-BmGNW61h.js.map → memory-IjwqFzBd.js.map} +1 -1
- package/public/assets/{messages-BvMMhoy-.js → messages-DjvWqHyn.js} +2 -2
- package/public/assets/{messages-BvMMhoy-.js.map → messages-DjvWqHyn.js.map} +1 -1
- package/public/assets/{orchestrators-DsstaupT.js → orchestrators-D2IqDxDT.js} +2 -2
- package/public/assets/{orchestrators-DsstaupT.js.map → orchestrators-D2IqDxDT.js.map} +1 -1
- package/public/assets/{overview-kK6PTce3.js → overview-DKC3TbAh.js} +2 -2
- package/public/assets/{overview-kK6PTce3.js.map → overview-DKC3TbAh.js.map} +1 -1
- package/public/assets/{pairs-BEFvTW6X.js → pairs-WpKCPE1n.js} +2 -2
- package/public/assets/{pairs-BEFvTW6X.js.map → pairs-WpKCPE1n.js.map} +1 -1
- package/public/assets/{security-Dc5wZwv0.js → security-BF7ZtPQe.js} +2 -2
- package/public/assets/{security-Dc5wZwv0.js.map → security-BF7ZtPQe.js.map} +1 -1
- package/public/assets/{settings-CEtJrORa.js → settings-CQnjrTa-.js} +2 -2
- package/public/assets/{settings-CEtJrORa.js.map → settings-CQnjrTa-.js.map} +1 -1
- package/public/assets/{store-DkmReBlH.js → store-C9VcSo05.js} +2 -2
- package/public/assets/{store-DkmReBlH.js.map → store-C9VcSo05.js.map} +1 -1
- package/public/assets/{tasks-pQKtxqeV.js → tasks-CbN_GSSb.js} +2 -2
- package/public/assets/{tasks-pQKtxqeV.js.map → tasks-CbN_GSSb.js.map} +1 -1
- package/public/assets/{terminal-viewer-impl-Cc769mYy.js → terminal-viewer-impl-BJRohThT.js} +2 -2
- package/public/assets/{terminal-viewer-impl-Cc769mYy.js.map → terminal-viewer-impl-BJRohThT.js.map} +1 -1
- package/public/assets/{work-queue-DjAanr02.js → work-queue-C5xLBLmm.js} +2 -2
- package/public/assets/{work-queue-DjAanr02.js.map → work-queue-C5xLBLmm.js.map} +1 -1
- package/public/assets/{workspaces-DLBNyR4k.js → workspaces-D91H3wDX.js} +2 -2
- package/public/assets/{workspaces-DLBNyR4k.js.map → workspaces-D91H3wDX.js.map} +1 -1
- package/public/index.html +2 -2
- package/scripts/orchestrator-spawn-smoke.ts +2 -1
- package/src/automations.ts +2 -4
- package/src/managed-policy.ts +2 -4
- package/src/mcp.ts +3 -3
- package/src/ratchet-files.ts +37 -0
- package/src/routes/_shared.ts +376 -0
- package/src/routes/activity.ts +61 -0
- package/src/routes/agent-profiles.ts +47 -0
- package/src/routes/agent-sessions.ts +488 -0
- package/src/routes/agents-spawn.ts +274 -0
- package/src/routes/agents.ts +251 -0
- package/src/routes/artifacts.ts +226 -0
- package/src/routes/automations.ts +83 -0
- package/src/routes/commands.ts +317 -0
- package/src/routes/config.ts +66 -0
- package/src/routes/connectors.ts +108 -0
- package/src/routes/inbox.ts +142 -0
- package/src/routes/index.ts +293 -0
- package/src/routes/insights.ts +81 -0
- package/src/routes/integrations.ts +592 -0
- package/src/routes/memory.ts +337 -0
- package/src/routes/messages.ts +529 -0
- package/src/routes/orchestrator-bootstrap.ts +100 -0
- package/src/routes/orchestrator-proxy.ts +160 -0
- package/src/routes/orchestrator.ts +490 -0
- package/src/routes/pairs.ts +197 -0
- package/src/routes/provider-config.ts +112 -0
- package/src/routes/recipes.ts +113 -0
- package/src/routes/spawn-policy.ts +231 -0
- package/src/routes/spec.ts +54 -0
- package/src/routes/sse.ts +9 -0
- package/src/routes/stats.ts +32 -0
- package/src/routes/steward.ts +45 -0
- package/src/routes/tasks.ts +174 -0
- package/src/routes/tokens.ts +311 -0
- package/src/routes/workspaces.ts +355 -0
- package/src/routes.ts +3 -6892
- package/src/runtime-tokens.ts +17 -8
- package/src/security.ts +0 -2
- package/src/validation.ts +134 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Auto-split from routes.ts (#299). Domain: config.
|
|
2
|
+
import { ValidationError } from "../db";
|
|
3
|
+
import { cleanString } from "../validation";
|
|
4
|
+
import { deleteConfig, getConfig, getConfigHistory, listConfig, setConfig } from "../config-store";
|
|
5
|
+
import { emitConfigChanged } from "../sse";
|
|
6
|
+
import { error, json, normalizeConfigPathParam, parseBody, parseQueryInt, type Handler } from "./_shared";
|
|
7
|
+
import { isRecord } from "agent-relay-sdk";
|
|
8
|
+
|
|
9
|
+
export const getConfigNamespace: Handler = (_req, params) => {
|
|
10
|
+
const namespace = normalizeConfigPathParam(params.namespace, "namespace");
|
|
11
|
+
return json(listConfig(namespace));
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const getConfigKey: Handler = (_req, params) => {
|
|
15
|
+
const namespace = normalizeConfigPathParam(params.namespace, "namespace");
|
|
16
|
+
const key = normalizeConfigPathParam(params.key, "key");
|
|
17
|
+
const entry = getConfig(namespace, key);
|
|
18
|
+
return entry ? json(entry) : error("config not found", 404);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const putConfigKey: Handler = async (req, params) => {
|
|
22
|
+
const parsed = await parseBody<unknown>(req);
|
|
23
|
+
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
24
|
+
try {
|
|
25
|
+
if (!isRecord(parsed.body)) throw new ValidationError("JSON object body required");
|
|
26
|
+
if (!Object.prototype.hasOwnProperty.call(parsed.body, "value")) throw new ValidationError("value required");
|
|
27
|
+
const namespace = normalizeConfigPathParam(params.namespace, "namespace");
|
|
28
|
+
const key = normalizeConfigPathParam(params.key, "key");
|
|
29
|
+
const updatedBy = cleanString(parsed.body.updatedBy, "updatedBy", { max: 200 });
|
|
30
|
+
const entry = setConfig(namespace, key, parsed.body.value, updatedBy);
|
|
31
|
+
emitConfigChanged(entry.namespace, entry.key, entry.version);
|
|
32
|
+
return json(entry, entry.version === 1 ? 201 : 200);
|
|
33
|
+
} catch (e) {
|
|
34
|
+
if (e instanceof ValidationError) return error(e.message, 400);
|
|
35
|
+
throw e;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const deleteConfigKey: Handler = (req, params) => {
|
|
40
|
+
try {
|
|
41
|
+
const namespace = normalizeConfigPathParam(params.namespace, "namespace");
|
|
42
|
+
const key = normalizeConfigPathParam(params.key, "key");
|
|
43
|
+
const updatedBy = cleanString(new URL(req.url).searchParams.get("updatedBy") ?? undefined, "updatedBy", { max: 200 });
|
|
44
|
+
const existing = getConfig(namespace, key);
|
|
45
|
+
if (!existing) return error("config not found", 404);
|
|
46
|
+
deleteConfig(namespace, key, updatedBy);
|
|
47
|
+
emitConfigChanged(namespace, key, existing.version + 1);
|
|
48
|
+
return json({ ok: true });
|
|
49
|
+
} catch (e) {
|
|
50
|
+
if (e instanceof ValidationError) return error(e.message, 400);
|
|
51
|
+
throw e;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const getConfigKeyHistory: Handler = (req, params) => {
|
|
56
|
+
try {
|
|
57
|
+
const namespace = normalizeConfigPathParam(params.namespace, "namespace");
|
|
58
|
+
const key = normalizeConfigPathParam(params.key, "key");
|
|
59
|
+
const limitRaw = parseQueryInt(new URL(req.url).searchParams.get("limit"), { min: 1, max: 500 });
|
|
60
|
+
if (Number.isNaN(limitRaw)) return error("limit must be an integer between 1 and 500");
|
|
61
|
+
return json(getConfigHistory(namespace, key, limitRaw ?? undefined));
|
|
62
|
+
} catch (e) {
|
|
63
|
+
if (e instanceof ValidationError) return error(e.message, 400);
|
|
64
|
+
throw e;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// Auto-split from routes.ts (#299). Domain: connectors.
|
|
2
|
+
import { ValidationError } from "../db";
|
|
3
|
+
import { error, json, parseBody, type Handler } from "./_shared";
|
|
4
|
+
import { getConnector, listConnectors, markConnectorUnreachable, readConnectorConfig, registerConnectorManifest, runConnectorAction, writeConnectorConfig } from "../connectors";
|
|
5
|
+
import { isRecord } from "agent-relay-sdk";
|
|
6
|
+
import { optionalEnum } from "../validation";
|
|
7
|
+
|
|
8
|
+
const VALID_CONNECTOR_ACTIONS = ["install", "uninstall", "enable", "disable", "start", "stop", "restart", "status", "doctor"] as const;
|
|
9
|
+
|
|
10
|
+
export const getConnectors: Handler = () => json(listConnectors());
|
|
11
|
+
|
|
12
|
+
export const getConnectorById: Handler = (_req, params) => {
|
|
13
|
+
const connector = getConnector(params.id!);
|
|
14
|
+
return connector ? json(connector) : error("connector not found", 404);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const postConnectorRegister: Handler = async (req) => {
|
|
18
|
+
const parsed = await parseBody<unknown>(req);
|
|
19
|
+
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
20
|
+
try {
|
|
21
|
+
if (!isRecord(parsed.body)) throw new ValidationError("JSON object body required");
|
|
22
|
+
const manifest = isRecord(parsed.body.manifest) ? parsed.body.manifest : parsed.body;
|
|
23
|
+
const config = isRecord(parsed.body.config) ? parsed.body.config : undefined;
|
|
24
|
+
const state = isRecord(parsed.body.state) ? parsed.body.state : undefined;
|
|
25
|
+
return json(registerConnectorManifest(manifest as any, { config, state }), 201);
|
|
26
|
+
} catch (e) {
|
|
27
|
+
if (e instanceof ValidationError) return error(e.message, 400);
|
|
28
|
+
throw e;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const postConnectorAction: Handler = async (req, params) => {
|
|
33
|
+
const parsed = await parseBody<unknown>(req);
|
|
34
|
+
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
35
|
+
try {
|
|
36
|
+
if (!isRecord(parsed.body)) throw new ValidationError("JSON object body required");
|
|
37
|
+
const action = optionalEnum(parsed.body.action, "action", VALID_CONNECTOR_ACTIONS)!;
|
|
38
|
+
const result = await runConnectorAction(params.id!, action);
|
|
39
|
+
return json(result, result.ok ? 200 : 502);
|
|
40
|
+
} catch (e) {
|
|
41
|
+
if (e instanceof ValidationError) return error(e.message, e.message.includes("not found") ? 404 : 400);
|
|
42
|
+
throw e;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const getConnectorConfig: Handler = (_req, params) => {
|
|
47
|
+
try {
|
|
48
|
+
if (!getConnector(params.id!)) return error("connector not found", 404);
|
|
49
|
+
return json(readConnectorConfig(params.id!));
|
|
50
|
+
} catch (e) {
|
|
51
|
+
if (e instanceof ValidationError) return error(e.message, 400);
|
|
52
|
+
throw e;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const putConnectorConfig: Handler = async (req, params) => {
|
|
57
|
+
const parsed = await parseBody<unknown>(req);
|
|
58
|
+
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
59
|
+
try {
|
|
60
|
+
if (!getConnector(params.id!)) return error("connector not found", 404);
|
|
61
|
+
if (!isRecord(parsed.body)) throw new ValidationError("connector config must be an object");
|
|
62
|
+
return json(writeConnectorConfig(params.id!, parsed.body));
|
|
63
|
+
} catch (e) {
|
|
64
|
+
if (e instanceof ValidationError) return error(e.message, 400);
|
|
65
|
+
throw e;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const PROXYABLE_CONNECTOR_CALLS = new Set(["transcribe", "utterance", "speak"]);
|
|
70
|
+
|
|
71
|
+
function connectorAdvertisedEndpoint(connector: NonNullable<ReturnType<typeof getConnector>>): string | null {
|
|
72
|
+
const raw = connector.state?.raw;
|
|
73
|
+
if (isRecord(raw) && typeof raw.endpoint === "string" && raw.endpoint) return raw.endpoint;
|
|
74
|
+
const cfg = connector.config;
|
|
75
|
+
if (isRecord(cfg) && typeof cfg.endpoint === "string" && cfg.endpoint) return cfg.endpoint;
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const postConnectorCall: Handler = async (req, params) => {
|
|
80
|
+
const connector = getConnector(params.id!);
|
|
81
|
+
if (!connector) return error("connector not found", 404);
|
|
82
|
+
const name = params.name!;
|
|
83
|
+
if (!PROXYABLE_CONNECTOR_CALLS.has(name)) return error("unsupported connector call", 404);
|
|
84
|
+
const endpoint = connectorAdvertisedEndpoint(connector);
|
|
85
|
+
if (!endpoint) return error("connector is not running (no advertised endpoint)", 422);
|
|
86
|
+
try {
|
|
87
|
+
const body = await req.arrayBuffer();
|
|
88
|
+
const res = await fetch(`${endpoint.replace(/\/$/, "")}/${name}`, {
|
|
89
|
+
method: "POST",
|
|
90
|
+
headers: { "content-type": req.headers.get("content-type") || "application/octet-stream" },
|
|
91
|
+
body,
|
|
92
|
+
signal: AbortSignal.timeout(120_000),
|
|
93
|
+
});
|
|
94
|
+
return new Response(res.body, {
|
|
95
|
+
status: res.status,
|
|
96
|
+
headers: { "content-type": res.headers.get("content-type") || "application/json" },
|
|
97
|
+
});
|
|
98
|
+
} catch (e) {
|
|
99
|
+
// A connection error (refused/reset/DNS) means the advertised endpoint is
|
|
100
|
+
// genuinely down — reconcile the stale running:true so the dashboard stops
|
|
101
|
+
// claiming the connector is healthy. A timeout (AbortError) may just be a
|
|
102
|
+
// slow daemon, so leave its state alone.
|
|
103
|
+
if ((e as Error).name !== "AbortError") {
|
|
104
|
+
markConnectorUnreachable(params.id!, `endpoint unreachable: ${(e as Error).message}`);
|
|
105
|
+
}
|
|
106
|
+
return error(`failed to reach connector: ${(e as Error).message}`, 502);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// Auto-split from routes.ts (#299). Domain: inbox.
|
|
2
|
+
import { MAX_BODY_BYTES } from "../config";
|
|
3
|
+
import { ValidationError, createChatHistoryImport, deleteInboxDraft, getInboxState, listChatHistoryImports, setInboxDraft, setInboxThreadState } from "../db";
|
|
4
|
+
import { authorizeRoute, error, json, parseBody, parseQueryInt, type Handler } from "./_shared";
|
|
5
|
+
import { cleanNullablePositiveId, cleanOperatorId, cleanPositiveIdArray, cleanString } from "../validation";
|
|
6
|
+
import { isRecord } from "agent-relay-sdk";
|
|
7
|
+
|
|
8
|
+
function normalizeInboxThreadStateInput(body: unknown): {
|
|
9
|
+
operatorId: string;
|
|
10
|
+
peerId: string;
|
|
11
|
+
readCursorMessageId?: number | null;
|
|
12
|
+
archivedAtMessageId?: number | null;
|
|
13
|
+
} {
|
|
14
|
+
if (!isRecord(body)) throw new ValidationError("JSON object body required");
|
|
15
|
+
const input: {
|
|
16
|
+
operatorId: string;
|
|
17
|
+
peerId: string;
|
|
18
|
+
readCursorMessageId?: number | null;
|
|
19
|
+
archivedAtMessageId?: number | null;
|
|
20
|
+
} = {
|
|
21
|
+
operatorId: cleanOperatorId(body.operatorId),
|
|
22
|
+
peerId: cleanString(body.peerId, "peerId", { required: true, max: 200 })!,
|
|
23
|
+
};
|
|
24
|
+
const readCursorMessageId = cleanNullablePositiveId(body.readCursorMessageId, "readCursorMessageId");
|
|
25
|
+
if (readCursorMessageId !== undefined) input.readCursorMessageId = readCursorMessageId;
|
|
26
|
+
const archivedAtMessageId = cleanNullablePositiveId(body.archivedAtMessageId, "archivedAtMessageId");
|
|
27
|
+
if (archivedAtMessageId !== undefined) input.archivedAtMessageId = archivedAtMessageId;
|
|
28
|
+
return input;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function normalizeInboxDraftInput(body: unknown): {
|
|
32
|
+
operatorId: string;
|
|
33
|
+
peerId: string;
|
|
34
|
+
body: string;
|
|
35
|
+
subject?: string;
|
|
36
|
+
channel?: string;
|
|
37
|
+
} {
|
|
38
|
+
if (!isRecord(body)) throw new ValidationError("JSON object body required");
|
|
39
|
+
return {
|
|
40
|
+
operatorId: cleanOperatorId(body.operatorId),
|
|
41
|
+
peerId: cleanString(body.peerId, "peerId", { required: true, max: 200 })!,
|
|
42
|
+
body: cleanString(body.body, "body", { required: true, max: MAX_BODY_BYTES })!,
|
|
43
|
+
subject: cleanString(body.subject, "subject", { max: 200 }),
|
|
44
|
+
channel: cleanString(body.channel, "channel", { max: 120 }),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function normalizeChatHistoryImportInput(body: unknown): {
|
|
49
|
+
targetAgentId?: string;
|
|
50
|
+
targetSpawnRequestId?: string;
|
|
51
|
+
sourcePeerId: string;
|
|
52
|
+
sourceAgentId?: string;
|
|
53
|
+
sourceThreadId?: string;
|
|
54
|
+
sourceAgentLabel?: string;
|
|
55
|
+
importedBy?: string;
|
|
56
|
+
messageIds: number[];
|
|
57
|
+
} {
|
|
58
|
+
if (!isRecord(body)) throw new ValidationError("JSON object body required");
|
|
59
|
+
const targetAgentId = cleanString(body.targetAgentId, "targetAgentId", { max: 200 });
|
|
60
|
+
const targetSpawnRequestId = cleanString(body.targetSpawnRequestId, "targetSpawnRequestId", { max: 160 });
|
|
61
|
+
if (!targetAgentId && !targetSpawnRequestId) throw new ValidationError("targetAgentId or targetSpawnRequestId required");
|
|
62
|
+
return {
|
|
63
|
+
targetAgentId,
|
|
64
|
+
targetSpawnRequestId,
|
|
65
|
+
sourcePeerId: cleanString(body.sourcePeerId, "sourcePeerId", { required: true, max: 200 })!,
|
|
66
|
+
sourceAgentId: cleanString(body.sourceAgentId, "sourceAgentId", { max: 200 }),
|
|
67
|
+
sourceThreadId: cleanString(body.sourceThreadId, "sourceThreadId", { max: 240 }),
|
|
68
|
+
sourceAgentLabel: cleanString(body.sourceAgentLabel, "sourceAgentLabel", { max: 240 }),
|
|
69
|
+
importedBy: cleanOperatorId(body.importedBy),
|
|
70
|
+
messageIds: cleanPositiveIdArray(body.messageIds, "messageIds"),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const getInboxStateRoute: Handler = (req) => {
|
|
75
|
+
const url = new URL(req.url);
|
|
76
|
+
const operatorId = cleanOperatorId(url.searchParams.get("operatorId") ?? undefined);
|
|
77
|
+
return json(getInboxState(operatorId));
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export const patchInboxThreadState: Handler = async (req) => {
|
|
81
|
+
const parsed = await parseBody<unknown>(req);
|
|
82
|
+
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
83
|
+
try {
|
|
84
|
+
return json(setInboxThreadState(normalizeInboxThreadStateInput(parsed.body)));
|
|
85
|
+
} catch (e) {
|
|
86
|
+
if (e instanceof ValidationError) return error(e.message, 400);
|
|
87
|
+
throw e;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const putInboxDraft: Handler = async (req) => {
|
|
92
|
+
const parsed = await parseBody<unknown>(req);
|
|
93
|
+
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
94
|
+
try {
|
|
95
|
+
return json(setInboxDraft(normalizeInboxDraftInput(parsed.body)));
|
|
96
|
+
} catch (e) {
|
|
97
|
+
if (e instanceof ValidationError) return error(e.message, 400);
|
|
98
|
+
throw e;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export const deleteInboxDraftRoute: Handler = (req) => {
|
|
103
|
+
const url = new URL(req.url);
|
|
104
|
+
try {
|
|
105
|
+
const operatorId = cleanOperatorId(url.searchParams.get("operatorId") ?? undefined);
|
|
106
|
+
const peerId = cleanString(url.searchParams.get("peerId") ?? undefined, "peerId", { required: true, max: 200 })!;
|
|
107
|
+
deleteInboxDraft(operatorId, peerId);
|
|
108
|
+
return json({ ok: true });
|
|
109
|
+
} catch (e) {
|
|
110
|
+
if (e instanceof ValidationError) return error(e.message, 400);
|
|
111
|
+
throw e;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export const getChatHistoryImportsRoute: Handler = (req) => {
|
|
116
|
+
const url = new URL(req.url);
|
|
117
|
+
try {
|
|
118
|
+
const targetAgentId = cleanString(url.searchParams.get("targetAgentId") ?? undefined, "targetAgentId", { max: 200 });
|
|
119
|
+
const targetSpawnRequestId = cleanString(url.searchParams.get("targetSpawnRequestId") ?? undefined, "targetSpawnRequestId", { max: 160 });
|
|
120
|
+
const limitRaw = parseQueryInt(url.searchParams.get("limit"), { min: 1, max: 500 });
|
|
121
|
+
if (Number.isNaN(limitRaw)) return error("limit must be an integer between 1 and 500");
|
|
122
|
+
return json(listChatHistoryImports({ targetAgentId, targetSpawnRequestId, limit: limitRaw ?? 100 }));
|
|
123
|
+
} catch (e) {
|
|
124
|
+
if (e instanceof ValidationError) return error(e.message, 400);
|
|
125
|
+
throw e;
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export const postChatHistoryImportRoute: Handler = async (req) => {
|
|
130
|
+
const parsed = await parseBody<unknown>(req);
|
|
131
|
+
if (!parsed.ok) return error(parsed.error, parsed.status);
|
|
132
|
+
try {
|
|
133
|
+
const input = normalizeChatHistoryImportInput(parsed.body);
|
|
134
|
+
const denied = authorizeRoute(req, { scope: "agent:write", resource: { agentId: input.targetAgentId, spawnRequestId: input.targetSpawnRequestId } });
|
|
135
|
+
if (denied) return denied;
|
|
136
|
+
const imported = createChatHistoryImport(input);
|
|
137
|
+
return json(imported, 201);
|
|
138
|
+
} catch (e) {
|
|
139
|
+
if (e instanceof ValidationError) return error(e.message, 400);
|
|
140
|
+
throw e;
|
|
141
|
+
}
|
|
142
|
+
};
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
// Auto-split from routes.ts (#299). Router: route table + matchRoute dispatch.
|
|
2
|
+
import { deleteAgentActiveMemories, deleteAgentById, findAgents, getAgentActiveMemories, getAgentById, getAgentContextSnapshots, getAgentReplyObligations, getAgentTimelineRoute, getAgents, getMessageArtifactsRoute, getTaskArtifactsRoute, patchAgentLabel, patchAgentReady, patchAgentStatus, patchAgentTags, postHeartbeat } from "./agents";
|
|
3
|
+
import { deleteAgentProfileRoute, getAgentProfileRoute, getAgentProfilesRoute, putAgentProfileRoute } from "./agent-profiles";
|
|
4
|
+
import { deleteAgentTerminalSession, postAgentAction, postAgentPermissionDecision, postAgentPrompt, postAgentTerminalSession } from "./agent-sessions";
|
|
5
|
+
import { deleteArtifactById, getArtifactById, getArtifactContent, getArtifacts, headArtifactContent, postArtifact } from "./artifacts";
|
|
6
|
+
import { deleteAutomationById, getAutomationById, getAutomationRuns, getAutomations, patchAutomation, postAutomation, postAutomationRun } from "./automations";
|
|
7
|
+
import { deleteCommandById, getProviderConfigRoute, getProviderConfigsRoute, getProvidersRoute, postProviderConfigTestRoute, putProviderConfigRoute } from "./provider-config";
|
|
8
|
+
import { deleteConfigKey, getConfigKey, getConfigKeyHistory, getConfigNamespace, putConfigKey } from "./config";
|
|
9
|
+
import { deleteInboxDraftRoute, getChatHistoryImportsRoute, getInboxStateRoute, patchInboxThreadState, postChatHistoryImportRoute, putInboxDraft } from "./inbox";
|
|
10
|
+
import { deleteMemoryRoute, getMemories, getMemoryBrokerInfo, getMemoryById, getMemoryStats, patchMemory, postMemory, postMemoryInject, postMemorySearch } from "./memory";
|
|
11
|
+
import { deleteMessageById, getCursorRoute, getMessageById, getMessageDeliveryRoute, getMessageStatusRoute, getMessageThread, getMessages, getQueuedMessagesRoute, patchMessage, postClaimMessage, postMessage, postMessageDeliveryAction, postMessageDeliveryAttempt, postMessageReaction, postRenewMessageClaim, postSystemBroadcast } from "./messages";
|
|
12
|
+
import { deleteOrchestratorById, getOrchestratorById, getOrchestrators, patchOrchestratorAgents, postOrchestrator, postOrchestratorAction, postOrchestratorHeartbeat } from "./orchestrator";
|
|
13
|
+
import { deleteSpawnPolicyRoute, getSpawnPoliciesHealth, getSpawnPoliciesRoute, getSpawnPolicyHealth, getSpawnPolicyRoute, getSpawnPolicyStatus, postSpawnPolicyRestart, postSpawnPolicyStart, postSpawnPolicyStop, putSpawnPolicyRoute } from "./spawn-policy";
|
|
14
|
+
import { deleteTokenProfileRoute, getTokenById, getTokenProfiles, getTokens, patchTokenProfile, postIntegrationRuntimeToken, postInteractiveRunnerRuntimeToken, postMcpRuntimeToken, postOrchestratorRunnerToken, postRuntimeTokenRenew, postToken, postTokenProfile, postTokenRevoke } from "./tokens";
|
|
15
|
+
import { deleteWorkspaceById, getWorkspaceById, getWorkspaceDiagnostics, getWorkspaceDiff, getWorkspaceGitState, getWorkspaceMergePreview, getWorkspaceOrphans, getWorkspaceStewards, getWorkspaces, postWorkspaceAction, postWorkspaceCleanupStale, postWorkspaceOrphanReclaim } from "./workspaces";
|
|
16
|
+
import { error, type Handler } from "./_shared";
|
|
17
|
+
import { getActivityEvents, postActivityEvent } from "./activity";
|
|
18
|
+
import { getAnalyticsRoute, getHealthRoute, getMaintenanceJobs, getStatsRoute, postMaintenanceJobRun, postSystemReap } from "./stats";
|
|
19
|
+
import { getApiDocs, getApiSpec } from "./spec";
|
|
20
|
+
import { getChannelBindings, getChannels, getIntegrations, postChannelActivity, postChannelBinding, postChannelEvent, postIntegrationEvent, putIntegrationRegistryRoute } from "./integrations";
|
|
21
|
+
import { getCommandById, getCommands, patchCommand, postCommand } from "./commands";
|
|
22
|
+
import { getConnectorById, getConnectorConfig, getConnectors, postConnectorAction, postConnectorCall, postConnectorRegister, putConnectorConfig } from "./connectors";
|
|
23
|
+
import { getEvents } from "./sse";
|
|
24
|
+
import { getHostDirectories, postAgent, postAgentSpawn, postRouteAdvice } from "./agents-spawn";
|
|
25
|
+
import { getInsightsConfigRoute, getInsightsObservationsRoute, postInsightsObservationRoute, putInsightsConfigRoute } from "./insights";
|
|
26
|
+
import { getOrchestratorDirectories, getOrchestratorFileRead, getOrchestratorFileStat, getOrchestratorFilesList, getOrchestratorLogs, getOrchestratorProviders, getOrchestratorSessions, getOrchestratorTerminal, getOrchestratorVersion, getOrchestratorWorkspaceProbe, postOrchestratorCreateDirectory, postOrchestratorTerminalInput, postOrchestratorTerminalResize } from "./orchestrator-proxy";
|
|
27
|
+
import { getPairById, getPairs, postAcceptPair, postHangupPair, postPair, postPairMessage, postRejectPair } from "./pairs";
|
|
28
|
+
import { getRecipeByName, getRecipeInstanceArtifacts, getRecipeInstanceById, getRecipeInstances, getRecipes, postRecipeInstanceArtifacts, postRecipeStart, postRecipeStop } from "./recipes";
|
|
29
|
+
import { getStewardConfigRoute, getWorkspaceConfigRoute, putStewardConfigRoute, putWorkspaceConfigRoute } from "./steward";
|
|
30
|
+
import { getTaskById, getTaskEvents, getTasks, patchTaskStatus, postClaimTask, postRenewTaskClaim } from "./tasks";
|
|
31
|
+
import { postMcp } from "../mcp";
|
|
32
|
+
import { postOrchestratorBootstrap, postOrchestratorBootstrapExchange } from "./orchestrator-bootstrap";
|
|
33
|
+
|
|
34
|
+
interface Route {
|
|
35
|
+
method: string;
|
|
36
|
+
pattern: RegExp;
|
|
37
|
+
paramNames: string[];
|
|
38
|
+
handler: Handler;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function route(method: string, path: string, handler: Handler): Route {
|
|
42
|
+
const paramNames: string[] = [];
|
|
43
|
+
const pattern = new RegExp(
|
|
44
|
+
"^" +
|
|
45
|
+
path.replace(/:(\w+)/g, (_, name) => {
|
|
46
|
+
paramNames.push(name);
|
|
47
|
+
return "([^/]+)";
|
|
48
|
+
}) +
|
|
49
|
+
"$"
|
|
50
|
+
);
|
|
51
|
+
return { method, pattern, paramNames, handler };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const routes: Route[] = [
|
|
55
|
+
route("POST", "/api/artifacts", postArtifact),
|
|
56
|
+
route("GET", "/api/artifacts", getArtifacts),
|
|
57
|
+
route("GET", "/api/artifacts/:id/content", getArtifactContent),
|
|
58
|
+
route("HEAD", "/api/artifacts/:id/content", headArtifactContent),
|
|
59
|
+
route("GET", "/api/artifacts/:id", getArtifactById),
|
|
60
|
+
route("DELETE", "/api/artifacts/:id", deleteArtifactById),
|
|
61
|
+
|
|
62
|
+
route("POST", "/api/memories", postMemory),
|
|
63
|
+
route("GET", "/api/memories", getMemories),
|
|
64
|
+
route("POST", "/api/memories/inject", postMemoryInject),
|
|
65
|
+
route("POST", "/api/memories/search", postMemorySearch),
|
|
66
|
+
route("GET", "/api/memories/stats", getMemoryStats),
|
|
67
|
+
route("GET", "/api/memories/broker", getMemoryBrokerInfo),
|
|
68
|
+
route("GET", "/api/memories/:id", getMemoryById),
|
|
69
|
+
route("PATCH", "/api/memories/:id", patchMemory),
|
|
70
|
+
route("DELETE", "/api/memories/:id", deleteMemoryRoute),
|
|
71
|
+
|
|
72
|
+
route("POST", "/api/agents", postAgent),
|
|
73
|
+
route("POST", "/api/agents/spawn", postAgentSpawn),
|
|
74
|
+
route("GET", "/api/agents", getAgents),
|
|
75
|
+
route("GET", "/api/agents/find", findAgents),
|
|
76
|
+
route("POST", "/api/route", postRouteAdvice),
|
|
77
|
+
route("GET", "/api/agents/spawn/directories", getHostDirectories),
|
|
78
|
+
route("GET", "/api/agents/:id/context-snapshots", getAgentContextSnapshots),
|
|
79
|
+
route("GET", "/api/agents/:id/timeline", getAgentTimelineRoute),
|
|
80
|
+
route("GET", "/api/agents/:id/active-memories", getAgentActiveMemories),
|
|
81
|
+
route("GET", "/api/agents/:id/reply-obligations", getAgentReplyObligations),
|
|
82
|
+
route("DELETE", "/api/agents/:id/active-memories", deleteAgentActiveMemories),
|
|
83
|
+
route("GET", "/api/agents/:id", getAgentById),
|
|
84
|
+
route("PATCH", "/api/agents/:id/status", patchAgentStatus),
|
|
85
|
+
route("PATCH", "/api/agents/:id/ready", patchAgentReady),
|
|
86
|
+
route("PATCH", "/api/agents/:id/label", patchAgentLabel),
|
|
87
|
+
route("PATCH", "/api/agents/:id/tags", patchAgentTags),
|
|
88
|
+
route("POST", "/api/agents/:id/heartbeat", postHeartbeat),
|
|
89
|
+
route("POST", "/api/agents/:id/actions", postAgentAction),
|
|
90
|
+
route("POST", "/api/agents/:id/prompt", postAgentPrompt),
|
|
91
|
+
route("POST", "/api/agents/:id/permission-decision", postAgentPermissionDecision),
|
|
92
|
+
route("POST", "/api/agents/:id/terminal-session", postAgentTerminalSession),
|
|
93
|
+
route("DELETE", "/api/agents/:id/terminal-session/:session", deleteAgentTerminalSession),
|
|
94
|
+
route("DELETE", "/api/agents/:id", deleteAgentById),
|
|
95
|
+
|
|
96
|
+
route("POST", "/api/orchestrators", postOrchestrator),
|
|
97
|
+
route("POST", "/api/orchestrators/bootstrap", postOrchestratorBootstrap),
|
|
98
|
+
route("POST", "/api/orchestrators/bootstrap/exchange", postOrchestratorBootstrapExchange),
|
|
99
|
+
route("GET", "/api/orchestrators", getOrchestrators),
|
|
100
|
+
route("GET", "/api/orchestrators/:id", getOrchestratorById),
|
|
101
|
+
route("POST", "/api/orchestrators/:id/heartbeat", postOrchestratorHeartbeat),
|
|
102
|
+
route("PATCH", "/api/orchestrators/:id/agents", patchOrchestratorAgents),
|
|
103
|
+
route("POST", "/api/orchestrators/:id/runner-token", postOrchestratorRunnerToken),
|
|
104
|
+
route("POST", "/api/orchestrators/:id/actions", postOrchestratorAction),
|
|
105
|
+
route("GET", "/api/orchestrators/:id/directories", getOrchestratorDirectories),
|
|
106
|
+
route("POST", "/api/orchestrators/:id/directories", postOrchestratorCreateDirectory),
|
|
107
|
+
route("GET", "/api/orchestrators/:id/files/list", getOrchestratorFilesList),
|
|
108
|
+
route("GET", "/api/orchestrators/:id/files/read", getOrchestratorFileRead),
|
|
109
|
+
route("GET", "/api/orchestrators/:id/files/stat", getOrchestratorFileStat),
|
|
110
|
+
route("GET", "/api/orchestrators/:id/workspace/probe", getOrchestratorWorkspaceProbe),
|
|
111
|
+
route("GET", "/api/orchestrators/:id/providers", getOrchestratorProviders),
|
|
112
|
+
route("GET", "/api/orchestrators/:id/sessions", getOrchestratorSessions),
|
|
113
|
+
route("GET", "/api/orchestrators/:id/version", getOrchestratorVersion),
|
|
114
|
+
route("GET", "/api/orchestrators/:id/logs/:session", getOrchestratorLogs),
|
|
115
|
+
route("GET", "/api/orchestrators/:id/terminal/:session", getOrchestratorTerminal),
|
|
116
|
+
route("POST", "/api/orchestrators/:id/terminal/:session/input", postOrchestratorTerminalInput),
|
|
117
|
+
route("POST", "/api/orchestrators/:id/terminal/:session/resize", postOrchestratorTerminalResize),
|
|
118
|
+
route("DELETE", "/api/orchestrators/:id", deleteOrchestratorById),
|
|
119
|
+
|
|
120
|
+
route("GET", "/api/workspaces", getWorkspaces),
|
|
121
|
+
// Static segments before :id so "/workspaces/orphans" isn't captured as an id.
|
|
122
|
+
route("GET", "/api/workspaces/orphans", getWorkspaceOrphans),
|
|
123
|
+
route("POST", "/api/workspaces/orphans/reclaim", postWorkspaceOrphanReclaim),
|
|
124
|
+
route("GET", "/api/workspaces/stewards", getWorkspaceStewards),
|
|
125
|
+
route("POST", "/api/workspaces/actions/cleanup-stale", postWorkspaceCleanupStale),
|
|
126
|
+
route("GET", "/api/workspaces/:id", getWorkspaceById),
|
|
127
|
+
route("GET", "/api/workspaces/:id/git-state", getWorkspaceGitState),
|
|
128
|
+
route("GET", "/api/workspaces/:id/merge-preview", getWorkspaceMergePreview),
|
|
129
|
+
route("GET", "/api/workspaces/:id/diagnostics", getWorkspaceDiagnostics),
|
|
130
|
+
route("GET", "/api/workspaces/:id/diff", getWorkspaceDiff),
|
|
131
|
+
route("POST", "/api/workspaces/:id/actions", postWorkspaceAction),
|
|
132
|
+
route("DELETE", "/api/workspaces/:id", deleteWorkspaceById),
|
|
133
|
+
|
|
134
|
+
route("POST", "/api/system/broadcast", postSystemBroadcast),
|
|
135
|
+
route("GET", "/api/recipes", getRecipes),
|
|
136
|
+
route("POST", "/api/recipes/start", postRecipeStart),
|
|
137
|
+
route("GET", "/api/recipes/instances", getRecipeInstances),
|
|
138
|
+
route("GET", "/api/recipes/instances/:id", getRecipeInstanceById),
|
|
139
|
+
route("GET", "/api/recipes/instances/:id/artifacts", getRecipeInstanceArtifacts),
|
|
140
|
+
route("POST", "/api/recipes/instances/:id/artifacts", postRecipeInstanceArtifacts),
|
|
141
|
+
route("POST", "/api/recipes/instances/:id/stop", postRecipeStop),
|
|
142
|
+
route("GET", "/api/recipes/:name", getRecipeByName),
|
|
143
|
+
route("GET", "/api/tokens", getTokens),
|
|
144
|
+
route("POST", "/api/tokens", postToken),
|
|
145
|
+
route("POST", "/api/runtime-tokens/renew", postRuntimeTokenRenew),
|
|
146
|
+
route("POST", "/api/runtime-tokens/interactive-runner", postInteractiveRunnerRuntimeToken),
|
|
147
|
+
route("POST", "/api/runtime-tokens/mcp-client", postMcpRuntimeToken),
|
|
148
|
+
route("POST", "/api/runtime-tokens/integration", postIntegrationRuntimeToken),
|
|
149
|
+
route("GET", "/api/token-profiles", getTokenProfiles),
|
|
150
|
+
route("POST", "/api/token-profiles", postTokenProfile),
|
|
151
|
+
route("PATCH", "/api/token-profiles/:id", patchTokenProfile),
|
|
152
|
+
route("DELETE", "/api/token-profiles/:id", deleteTokenProfileRoute),
|
|
153
|
+
route("GET", "/api/tokens/:jti", getTokenById),
|
|
154
|
+
route("POST", "/api/tokens/:jti/revoke", postTokenRevoke),
|
|
155
|
+
route("POST", "/api/commands", postCommand),
|
|
156
|
+
route("GET", "/api/commands", getCommands),
|
|
157
|
+
route("GET", "/api/commands/:id", getCommandById),
|
|
158
|
+
route("PATCH", "/api/commands/:id", patchCommand),
|
|
159
|
+
route("DELETE", "/api/commands/:id", deleteCommandById),
|
|
160
|
+
route("GET", "/api/agent-profiles", getAgentProfilesRoute),
|
|
161
|
+
route("GET", "/api/agent-profiles/:name", getAgentProfileRoute),
|
|
162
|
+
route("PUT", "/api/agent-profiles/:name", putAgentProfileRoute),
|
|
163
|
+
route("DELETE", "/api/agent-profiles/:name", deleteAgentProfileRoute),
|
|
164
|
+
route("GET", "/api/steward-config", getStewardConfigRoute),
|
|
165
|
+
route("PUT", "/api/steward-config", putStewardConfigRoute),
|
|
166
|
+
route("GET", "/api/workspace-config", getWorkspaceConfigRoute),
|
|
167
|
+
route("PUT", "/api/workspace-config", putWorkspaceConfigRoute),
|
|
168
|
+
route("GET", "/api/insights/config", getInsightsConfigRoute),
|
|
169
|
+
route("PUT", "/api/insights/config", putInsightsConfigRoute),
|
|
170
|
+
route("GET", "/api/insights/observations", getInsightsObservationsRoute),
|
|
171
|
+
route("POST", "/api/insights/observations", postInsightsObservationRoute),
|
|
172
|
+
route("GET", "/api/config/:namespace", getConfigNamespace),
|
|
173
|
+
route("GET", "/api/config/:namespace/:key/history", getConfigKeyHistory),
|
|
174
|
+
route("GET", "/api/config/:namespace/:key", getConfigKey),
|
|
175
|
+
route("PUT", "/api/config/:namespace/:key", putConfigKey),
|
|
176
|
+
route("DELETE", "/api/config/:namespace/:key", deleteConfigKey),
|
|
177
|
+
route("GET", "/api/spawn-policies", getSpawnPoliciesRoute),
|
|
178
|
+
route("GET", "/api/spawn-policy/:name", getSpawnPolicyRoute),
|
|
179
|
+
route("PUT", "/api/spawn-policy/:name", putSpawnPolicyRoute),
|
|
180
|
+
route("DELETE", "/api/spawn-policy/:name", deleteSpawnPolicyRoute),
|
|
181
|
+
route("POST", "/api/spawn-policy/:name/start", postSpawnPolicyStart),
|
|
182
|
+
route("POST", "/api/spawn-policy/:name/stop", postSpawnPolicyStop),
|
|
183
|
+
route("POST", "/api/spawn-policy/:name/restart", postSpawnPolicyRestart),
|
|
184
|
+
route("GET", "/api/spawn-policies/health", getSpawnPoliciesHealth),
|
|
185
|
+
route("GET", "/api/spawn-policy/:name/status", getSpawnPolicyStatus),
|
|
186
|
+
route("GET", "/api/spawn-policy/:name/health", getSpawnPolicyHealth),
|
|
187
|
+
route("GET", "/api/providers", getProvidersRoute),
|
|
188
|
+
route("GET", "/api/providers/config", getProviderConfigsRoute),
|
|
189
|
+
route("GET", "/api/providers/:provider/config", getProviderConfigRoute),
|
|
190
|
+
route("PUT", "/api/providers/:provider/config", putProviderConfigRoute),
|
|
191
|
+
route("POST", "/api/providers/:provider/config/test", postProviderConfigTestRoute),
|
|
192
|
+
|
|
193
|
+
route("POST", "/api/mcp", postMcp),
|
|
194
|
+
|
|
195
|
+
route("POST", "/api/messages", postMessage),
|
|
196
|
+
route("GET", "/api/messages", getMessages),
|
|
197
|
+
route("GET", "/api/messages/queued", getQueuedMessagesRoute),
|
|
198
|
+
route("GET", "/api/messages/cursor", getCursorRoute),
|
|
199
|
+
route("GET", "/api/messages/:id/status", getMessageStatusRoute),
|
|
200
|
+
route("GET", "/api/messages/:id/delivery", getMessageDeliveryRoute),
|
|
201
|
+
route("GET", "/api/messages/:id/artifacts", getMessageArtifactsRoute),
|
|
202
|
+
route("POST", "/api/messages/:id/delivery/attempts", postMessageDeliveryAttempt),
|
|
203
|
+
route("POST", "/api/messages/:id/delivery/actions", postMessageDeliveryAction),
|
|
204
|
+
route("GET", "/api/messages/:id", getMessageById),
|
|
205
|
+
route("GET", "/api/messages/:id/thread", getMessageThread),
|
|
206
|
+
route("POST", "/api/messages/:id/reactions", postMessageReaction),
|
|
207
|
+
route("POST", "/api/messages/:id/claim", postClaimMessage),
|
|
208
|
+
route("POST", "/api/messages/:id/claim/renew", postRenewMessageClaim),
|
|
209
|
+
route("PATCH", "/api/messages/:id", patchMessage),
|
|
210
|
+
route("DELETE", "/api/messages/:id", deleteMessageById),
|
|
211
|
+
|
|
212
|
+
route("GET", "/api/inbox/state", getInboxStateRoute),
|
|
213
|
+
route("PATCH", "/api/inbox/threads", patchInboxThreadState),
|
|
214
|
+
route("PUT", "/api/inbox/drafts", putInboxDraft),
|
|
215
|
+
route("DELETE", "/api/inbox/drafts", deleteInboxDraftRoute),
|
|
216
|
+
route("GET", "/api/chat/history-imports", getChatHistoryImportsRoute),
|
|
217
|
+
route("POST", "/api/chat/history-imports", postChatHistoryImportRoute),
|
|
218
|
+
|
|
219
|
+
route("GET", "/api/activity", getActivityEvents),
|
|
220
|
+
route("POST", "/api/activity", postActivityEvent),
|
|
221
|
+
|
|
222
|
+
route("GET", "/api/connectors", getConnectors),
|
|
223
|
+
route("POST", "/api/connectors", postConnectorRegister),
|
|
224
|
+
route("GET", "/api/connectors/:id", getConnectorById),
|
|
225
|
+
route("POST", "/api/connectors/:id/actions", postConnectorAction),
|
|
226
|
+
route("GET", "/api/connectors/:id/config", getConnectorConfig),
|
|
227
|
+
route("PUT", "/api/connectors/:id/config", putConnectorConfig),
|
|
228
|
+
route("POST", "/api/connectors/:id/call/:name", postConnectorCall),
|
|
229
|
+
|
|
230
|
+
route("GET", "/api/channels", getChannels),
|
|
231
|
+
route("POST", "/api/channels/:id/events", postChannelEvent),
|
|
232
|
+
route("POST", "/api/channels/:id/activities", postChannelActivity),
|
|
233
|
+
route("GET", "/api/channel-bindings", getChannelBindings),
|
|
234
|
+
route("POST", "/api/channel-bindings", postChannelBinding),
|
|
235
|
+
route("GET", "/api/integrations", getIntegrations),
|
|
236
|
+
route("PUT", "/api/integrations/:name", putIntegrationRegistryRoute),
|
|
237
|
+
route("POST", "/api/integrations/events", postIntegrationEvent),
|
|
238
|
+
route("GET", "/api/automations", getAutomations),
|
|
239
|
+
route("POST", "/api/automations", postAutomation),
|
|
240
|
+
route("GET", "/api/automation-runs", getAutomationRuns),
|
|
241
|
+
route("GET", "/api/automations/:id", getAutomationById),
|
|
242
|
+
route("PATCH", "/api/automations/:id", patchAutomation),
|
|
243
|
+
route("DELETE", "/api/automations/:id", deleteAutomationById),
|
|
244
|
+
route("POST", "/api/automations/:id/run", postAutomationRun),
|
|
245
|
+
route("GET", "/api/tasks", getTasks),
|
|
246
|
+
route("GET", "/api/tasks/:id", getTaskById),
|
|
247
|
+
route("GET", "/api/tasks/:id/artifacts", getTaskArtifactsRoute),
|
|
248
|
+
route("GET", "/api/tasks/:id/events", getTaskEvents),
|
|
249
|
+
route("POST", "/api/tasks/:id/claim", postClaimTask),
|
|
250
|
+
route("POST", "/api/tasks/:id/claim/renew", postRenewTaskClaim),
|
|
251
|
+
route("PATCH", "/api/tasks/:id/status", patchTaskStatus),
|
|
252
|
+
|
|
253
|
+
route("POST", "/api/pairs", postPair),
|
|
254
|
+
route("GET", "/api/pairs", getPairs),
|
|
255
|
+
route("GET", "/api/pairs/:id", getPairById),
|
|
256
|
+
route("POST", "/api/pairs/:id/accept", postAcceptPair),
|
|
257
|
+
route("POST", "/api/pairs/:id/reject", postRejectPair),
|
|
258
|
+
route("POST", "/api/pairs/:id/hangup", postHangupPair),
|
|
259
|
+
route("POST", "/api/pairs/:id/messages", postPairMessage),
|
|
260
|
+
|
|
261
|
+
route("GET", "/api/spec", getApiSpec),
|
|
262
|
+
route("GET", "/api/docs", getApiDocs),
|
|
263
|
+
|
|
264
|
+
route("GET", "/api/events", getEvents),
|
|
265
|
+
route("GET", "/api/stats", getStatsRoute),
|
|
266
|
+
route("GET", "/api/stats/analytics", getAnalyticsRoute),
|
|
267
|
+
route("GET", "/api/health", getHealthRoute),
|
|
268
|
+
route("GET", "/api/maintenance/jobs", getMaintenanceJobs),
|
|
269
|
+
route("POST", "/api/maintenance/jobs/:id/run", postMaintenanceJobRun),
|
|
270
|
+
route("POST", "/api/system/reap", postSystemReap),
|
|
271
|
+
];
|
|
272
|
+
|
|
273
|
+
export function matchRoute(
|
|
274
|
+
method: string,
|
|
275
|
+
pathname: string
|
|
276
|
+
): { handler: Handler; params: Record<string, string> } | null {
|
|
277
|
+
for (const r of routes) {
|
|
278
|
+
if (r.method !== method) continue;
|
|
279
|
+
const match = pathname.match(r.pattern);
|
|
280
|
+
if (!match) continue;
|
|
281
|
+
|
|
282
|
+
const params: Record<string, string> = {};
|
|
283
|
+
try {
|
|
284
|
+
r.paramNames.forEach((name, i) => {
|
|
285
|
+
params[name] = decodeURIComponent(match[i + 1]!);
|
|
286
|
+
});
|
|
287
|
+
} catch {
|
|
288
|
+
return { handler: () => error("invalid url encoding"), params: {} };
|
|
289
|
+
}
|
|
290
|
+
return { handler: r.handler, params };
|
|
291
|
+
}
|
|
292
|
+
return null;
|
|
293
|
+
}
|