@cognidesk/http 0.0.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.
@@ -0,0 +1,71 @@
1
+ import { CreateRuntimeConversationInput, ConversationRecord, HandleUserMessageInput, HandleUserMessageResult, SubmitWidgetInput, RuntimeEvent, CustomRuntimeEventDefinition, JourneyEventDefinition, EmitJourneyEventResult, EmitIntermediateMessageInput, EmitGeneratedPreambleInput, CompactConversationInput, CompactConversationResult, RequestHandoffInput, ResumeConversationInput, StartVoiceConversationInput, StartVoiceResult, StartVoiceSegmentInput, ReplayConversationInput, ReplayConversationResult, RuntimeSnapshot, CognideskRuntime, VoiceSocketMetadata } from '@cognidesk/core';
2
+
3
+ interface CognideskHttpRuntime {
4
+ createConversation(input: CreateRuntimeConversationInput): Promise<ConversationRecord>;
5
+ handleUserMessage(input: HandleUserMessageInput): Promise<HandleUserMessageResult>;
6
+ submitWidget?(input: SubmitWidgetInput): Promise<RuntimeEvent>;
7
+ emitCustomEvent?(input: {
8
+ conversationId: string;
9
+ event: CustomRuntimeEventDefinition;
10
+ payload: unknown;
11
+ }): Promise<RuntimeEvent>;
12
+ emitJourneyEvent?(input: {
13
+ conversationId: string;
14
+ event: JourneyEventDefinition;
15
+ payload: unknown;
16
+ routing?: "none" | "activeJourneyOnly" | "full" | "targeted";
17
+ target?: {
18
+ journeyId?: string;
19
+ stateId?: string;
20
+ };
21
+ app?: unknown;
22
+ signal?: AbortSignal;
23
+ }): Promise<EmitJourneyEventResult>;
24
+ emitIntermediateMessage?(input: EmitIntermediateMessageInput): Promise<{
25
+ events: RuntimeEvent[];
26
+ }>;
27
+ emitGeneratedPreamble?(input: EmitGeneratedPreambleInput): Promise<{
28
+ text: string;
29
+ events: RuntimeEvent[];
30
+ }>;
31
+ compactConversation?(input: CompactConversationInput): Promise<CompactConversationResult<unknown>>;
32
+ closeConversation?(conversationId: string, reason?: string): Promise<ConversationRecord>;
33
+ requestHandoff?(input: RequestHandoffInput): Promise<{
34
+ conversation: ConversationRecord;
35
+ event: RuntimeEvent;
36
+ }>;
37
+ resumeConversation?(input: ResumeConversationInput): Promise<{
38
+ conversation: ConversationRecord;
39
+ event: RuntimeEvent;
40
+ }>;
41
+ startVoiceConversation?(input: StartVoiceConversationInput): Promise<StartVoiceResult>;
42
+ startVoiceSegment?(input: StartVoiceSegmentInput): Promise<StartVoiceResult>;
43
+ replayConversation?(input: ReplayConversationInput): Promise<ReplayConversationResult>;
44
+ getSnapshot?(conversationId: string): Promise<RuntimeSnapshot | null>;
45
+ listEvents(conversationId: string, afterOffset?: number): Promise<RuntimeEvent[]>;
46
+ }
47
+ interface VoiceSocketHandshakeInput {
48
+ result: StartVoiceResult;
49
+ request: Request;
50
+ basePath: string;
51
+ }
52
+ interface VoiceSocketHandshake {
53
+ createSocket(input: VoiceSocketHandshakeInput): Promise<VoiceSocketMetadata>;
54
+ }
55
+ interface CognideskHttpHandlerOptions {
56
+ runtime: CognideskHttpRuntime | CognideskRuntime;
57
+ basePath?: string;
58
+ agentId?: string;
59
+ voice?: VoiceSocketHandshake;
60
+ customEvents?: CustomRuntimeEventDefinition[];
61
+ journeyEvents?: JourneyEventDefinition[];
62
+ ssePollIntervalMs?: number;
63
+ cors?: boolean;
64
+ }
65
+ interface CognideskHttpHandler {
66
+ handle(request: Request): Promise<Response>;
67
+ }
68
+
69
+ declare function createCognideskHttpHandler(options: CognideskHttpHandlerOptions): CognideskHttpHandler;
70
+
71
+ export { type CognideskHttpHandler, type CognideskHttpHandlerOptions, type CognideskHttpRuntime, createCognideskHttpHandler };
package/dist/index.js ADDED
@@ -0,0 +1,448 @@
1
+ // src/responses.ts
2
+ var HttpInputError = class extends Error {
3
+ status = 400;
4
+ };
5
+ async function readJson(request) {
6
+ if (!request.body) return {};
7
+ try {
8
+ return await request.json();
9
+ } catch {
10
+ throw new HttpInputError("Request body must be valid JSON.");
11
+ }
12
+ }
13
+ function json(body, status, options) {
14
+ return new Response(JSON.stringify(body), {
15
+ status,
16
+ headers: withCors({
17
+ "content-type": "application/json; charset=utf-8"
18
+ }, options)
19
+ });
20
+ }
21
+ function emptyResponse(status, options) {
22
+ return new Response(null, {
23
+ status,
24
+ headers: withCors({}, options)
25
+ });
26
+ }
27
+ function withCors(headers, options) {
28
+ if (!options.cors) return headers;
29
+ return {
30
+ ...headers,
31
+ "access-control-allow-origin": "*",
32
+ "access-control-allow-methods": "GET,POST,OPTIONS",
33
+ "access-control-allow-headers": "content-type,authorization"
34
+ };
35
+ }
36
+
37
+ // src/path.ts
38
+ function normalizeBasePath(basePath) {
39
+ if (!basePath || basePath === "/") return "";
40
+ return basePath.startsWith("/") ? basePath.replace(/\/$/, "") : `/${basePath.replace(/\/$/, "")}`;
41
+ }
42
+ function stripBasePath(pathname, basePath) {
43
+ if (!basePath) return pathname;
44
+ if (pathname === basePath) return "/";
45
+ if (!pathname.startsWith(`${basePath}/`)) return null;
46
+ return pathname.slice(basePath.length);
47
+ }
48
+ function parseOptionalInteger(value) {
49
+ if (value === null || value === "") return void 0;
50
+ if (!/^(0|[1-9]\d*)$/.test(value)) {
51
+ throw new HttpInputError("after must be a non-negative integer.");
52
+ }
53
+ return Number(value);
54
+ }
55
+
56
+ // src/sse.ts
57
+ function streamEvents(options) {
58
+ const encoder = new TextEncoder();
59
+ let offset = options.afterOffset ?? 0;
60
+ let closed = false;
61
+ const stream = new ReadableStream({
62
+ start(controller) {
63
+ const close = () => {
64
+ if (closed) return;
65
+ closed = true;
66
+ try {
67
+ controller.close();
68
+ } catch {
69
+ }
70
+ };
71
+ options.signal.addEventListener("abort", close, { once: true });
72
+ const poll = async () => {
73
+ if (closed) return;
74
+ try {
75
+ const events = await options.runtime.listEvents(options.conversationId, offset);
76
+ if (closed) return;
77
+ for (const event of events) {
78
+ if (closed) return;
79
+ offset = event.offset;
80
+ controller.enqueue(encoder.encode(formatSseEvent(event)));
81
+ }
82
+ } catch (error) {
83
+ if (closed) return;
84
+ controller.enqueue(encoder.encode(formatSseError(error)));
85
+ }
86
+ if (!closed) setTimeout(poll, options.pollIntervalMs);
87
+ };
88
+ if (!closed) controller.enqueue(encoder.encode(": cognidesk stream ready\n\n"));
89
+ void poll();
90
+ },
91
+ cancel() {
92
+ closed = true;
93
+ }
94
+ });
95
+ return new Response(stream, {
96
+ status: 200,
97
+ headers: withCors({
98
+ "content-type": "text/event-stream; charset=utf-8",
99
+ "cache-control": "no-cache, no-transform",
100
+ connection: "keep-alive"
101
+ }, options.responseOptions)
102
+ });
103
+ }
104
+ function formatSseEvent(event) {
105
+ return [
106
+ `id: ${event.offset}`,
107
+ "event: event",
108
+ `data: ${JSON.stringify(event)}`,
109
+ "",
110
+ ""
111
+ ].join("\n");
112
+ }
113
+ function formatSseError(error) {
114
+ return [
115
+ "event: error",
116
+ `data: ${JSON.stringify({ error: error instanceof Error ? error.message : "Unknown error" })}`,
117
+ "",
118
+ ""
119
+ ].join("\n");
120
+ }
121
+
122
+ // src/handler.ts
123
+ function createCognideskHttpHandler(options) {
124
+ const basePath = normalizeBasePath(options.basePath ?? "");
125
+ const pollIntervalMs = options.ssePollIntervalMs ?? 500;
126
+ return {
127
+ async handle(request) {
128
+ if (request.method === "OPTIONS" && options.cors) {
129
+ return emptyResponse(204, options);
130
+ }
131
+ try {
132
+ const url = new URL(request.url);
133
+ const path = stripBasePath(url.pathname, basePath);
134
+ if (path === null) return json({ error: "Not found" }, 404, options);
135
+ if (request.method === "POST" && path === "/conversations") {
136
+ const body = await readObject(request);
137
+ const agentId = optionalString(body, "agentId") ?? options.agentId;
138
+ if (!agentId) return json({ error: "agentId is required" }, 400, options);
139
+ const conversation = await options.runtime.createConversation({
140
+ ...optionalStringProperty(body, "id"),
141
+ agentId,
142
+ context: body.context ?? {}
143
+ });
144
+ return json({ conversation }, 201, options);
145
+ }
146
+ if (request.method === "POST" && path === "/voice/conversations") {
147
+ if (!options.runtime.startVoiceConversation) return json({ error: "Voice conversations are not supported by this runtime" }, 501, options);
148
+ if (!options.voice?.createSocket) return json({ error: "Voice socket handshakes are not configured" }, 501, options);
149
+ const body = await readObject(request);
150
+ const agentId = optionalString(body, "agentId") ?? options.agentId;
151
+ if (!agentId) return json({ error: "agentId is required" }, 400, options);
152
+ const result = await options.runtime.startVoiceConversation({
153
+ ...optionalStringProperty(body, "id"),
154
+ agentId,
155
+ context: body.context ?? {},
156
+ ...optionalVoiceClient(body),
157
+ ...body.app !== void 0 ? { app: body.app } : {}
158
+ });
159
+ const socket = await options.voice.createSocket({ result, request, basePath });
160
+ return json(withVoiceEventsUrl({ ...result, socket }, basePath), 201, options);
161
+ }
162
+ const voiceSegmentMatch = path.match(/^\/conversations\/([^/]+)\/voice-segments$/);
163
+ if (request.method === "POST" && voiceSegmentMatch) {
164
+ if (!options.runtime.startVoiceSegment) return json({ error: "Voice segments are not supported by this runtime" }, 501, options);
165
+ if (!options.voice?.createSocket) return json({ error: "Voice socket handshakes are not configured" }, 501, options);
166
+ const conversationId = decodeURIComponent(voiceSegmentMatch[1] ?? "");
167
+ const body = await readObject(request);
168
+ const result = await options.runtime.startVoiceSegment({
169
+ conversationId,
170
+ ...optionalVoiceClient(body),
171
+ ...body.app !== void 0 ? { app: body.app } : {}
172
+ });
173
+ const socket = await options.voice.createSocket({ result, request, basePath });
174
+ return json(withVoiceEventsUrl({ ...result, socket }, basePath), 200, options);
175
+ }
176
+ const messageMatch = path.match(/^\/conversations\/([^/]+)\/messages$/);
177
+ if (request.method === "POST" && messageMatch) {
178
+ const conversationId = decodeURIComponent(messageMatch[1] ?? "");
179
+ const body = await readObject(request);
180
+ const text = optionalString(body, "text") ?? optionalString(body, "message");
181
+ if (!text) return json({ error: "message is required" }, 400, options);
182
+ const result = await options.runtime.handleUserMessage({
183
+ conversationId,
184
+ text,
185
+ ...body.turn !== void 0 ? { turn: body.turn } : {},
186
+ ...body.app !== void 0 ? { app: body.app } : {},
187
+ signal: request.signal
188
+ });
189
+ return json(result, 200, options);
190
+ }
191
+ const customEventMatch = path.match(/^\/conversations\/([^/]+)\/custom-events\/([^/]+)$/);
192
+ if (request.method === "POST" && customEventMatch) {
193
+ if (!options.runtime.emitCustomEvent) return json({ error: "Custom events are not supported by this runtime" }, 501, options);
194
+ const conversationId = decodeURIComponent(customEventMatch[1] ?? "");
195
+ const eventName = decodeURIComponent(customEventMatch[2] ?? "");
196
+ const event = options.customEvents?.find((candidate) => candidate.name === eventName);
197
+ if (!event) return json({ error: `Custom event '${eventName}' is not registered with the HTTP handler` }, 404, options);
198
+ const body = await readObject(request);
199
+ const emitted = await options.runtime.emitCustomEvent({
200
+ conversationId,
201
+ event,
202
+ payload: body.payload
203
+ });
204
+ return json({ event: emitted }, 200, options);
205
+ }
206
+ const journeyEventMatch = path.match(/^\/conversations\/([^/]+)\/journey-events\/([^/]+)$/);
207
+ if (request.method === "POST" && journeyEventMatch) {
208
+ if (!options.runtime.emitJourneyEvent) return json({ error: "Journey events are not supported by this runtime" }, 501, options);
209
+ const conversationId = decodeURIComponent(journeyEventMatch[1] ?? "");
210
+ const eventName = decodeURIComponent(journeyEventMatch[2] ?? "");
211
+ const event = options.journeyEvents?.find((candidate) => candidate.name === eventName);
212
+ if (!event) return json({ error: `Journey event '${eventName}' is not registered with the HTTP handler` }, 404, options);
213
+ const body = await readObject(request);
214
+ const routing = optionalRouting(body, "routing");
215
+ const target = optionalTarget(body, "target");
216
+ const result = await options.runtime.emitJourneyEvent({
217
+ conversationId,
218
+ event,
219
+ payload: body.payload,
220
+ ...routing ? { routing } : {},
221
+ ...target ? { target } : {},
222
+ ...body.app !== void 0 ? { app: body.app } : {},
223
+ signal: request.signal
224
+ });
225
+ return json(result, 200, options);
226
+ }
227
+ const handoffMatch = path.match(/^\/conversations\/([^/]+)\/handoff$/);
228
+ if (request.method === "POST" && handoffMatch) {
229
+ if (!options.runtime.requestHandoff) return json({ error: "Handoff is not supported by this runtime" }, 501, options);
230
+ const conversationId = decodeURIComponent(handoffMatch[1] ?? "");
231
+ const body = await readObject(request);
232
+ const reason = optionalString(body, "reason");
233
+ if (!reason) return json({ error: "reason is required" }, 400, options);
234
+ const result = await options.runtime.requestHandoff({
235
+ conversationId,
236
+ reason,
237
+ ...optionalStringProperty(body, "summary"),
238
+ ...body.payload !== void 0 ? { payload: body.payload } : {}
239
+ });
240
+ return json(result, 200, options);
241
+ }
242
+ const closeMatch = path.match(/^\/conversations\/([^/]+)\/close$/);
243
+ if (request.method === "POST" && closeMatch) {
244
+ if (!options.runtime.closeConversation) return json({ error: "Conversation closure is not supported by this runtime" }, 501, options);
245
+ const conversationId = decodeURIComponent(closeMatch[1] ?? "");
246
+ const body = await readObject(request);
247
+ const conversation = await options.runtime.closeConversation(
248
+ conversationId,
249
+ optionalString(body, "reason")
250
+ );
251
+ return json({ conversation }, 200, options);
252
+ }
253
+ const resumeMatch = path.match(/^\/conversations\/([^/]+)\/resume$/);
254
+ if (request.method === "POST" && resumeMatch) {
255
+ if (!options.runtime.resumeConversation) return json({ error: "Conversation resume is not supported by this runtime" }, 501, options);
256
+ const conversationId = decodeURIComponent(resumeMatch[1] ?? "");
257
+ const body = await readObject(request);
258
+ const result = await options.runtime.resumeConversation({
259
+ conversationId,
260
+ ...optionalStringProperty(body, "reason"),
261
+ ...body.payload !== void 0 ? { payload: body.payload } : {}
262
+ });
263
+ return json(result, 200, options);
264
+ }
265
+ const intermediateMessageMatch = path.match(/^\/conversations\/([^/]+)\/intermediate-messages$/);
266
+ if (request.method === "POST" && intermediateMessageMatch) {
267
+ if (!options.runtime.emitIntermediateMessage) return json({ error: "Intermediate messages are not supported by this runtime" }, 501, options);
268
+ const conversationId = decodeURIComponent(intermediateMessageMatch[1] ?? "");
269
+ const body = await readObject(request);
270
+ const text = optionalString(body, "text");
271
+ if (!text) return json({ error: "text is required" }, 400, options);
272
+ const result = await options.runtime.emitIntermediateMessage({
273
+ conversationId,
274
+ text,
275
+ ...body.visibleToModel === true ? { visibleToModel: true } : {}
276
+ });
277
+ return json(result, 200, options);
278
+ }
279
+ const preambleMatch = path.match(/^\/conversations\/([^/]+)\/preambles$/);
280
+ if (request.method === "POST" && preambleMatch) {
281
+ if (!options.runtime.emitGeneratedPreamble) return json({ error: "Generated preambles are not supported by this runtime" }, 501, options);
282
+ const conversationId = decodeURIComponent(preambleMatch[1] ?? "");
283
+ const body = await readObject(request);
284
+ const maxWords = optionalNonNegativeNumber(body, "maxWords");
285
+ const result = await options.runtime.emitGeneratedPreamble({
286
+ conversationId,
287
+ ...optionalStringProperty(body, "purpose"),
288
+ ...maxWords !== void 0 ? { maxWords } : {},
289
+ signal: request.signal
290
+ });
291
+ return json(result, 200, options);
292
+ }
293
+ const compactionMatch = path.match(/^\/conversations\/([^/]+)\/compact$/);
294
+ if (request.method === "POST" && compactionMatch) {
295
+ if (!options.runtime.compactConversation) return json({ error: "Conversation compaction is not supported by this runtime" }, 501, options);
296
+ const conversationId = decodeURIComponent(compactionMatch[1] ?? "");
297
+ const body = await readObject(request);
298
+ const fromOffset = optionalNonNegativeNumber(body, "fromOffset");
299
+ const toOffset = optionalNonNegativeNumber(body, "toOffset");
300
+ const result = await options.runtime.compactConversation({
301
+ conversationId,
302
+ ...fromOffset !== void 0 ? { fromOffset } : {},
303
+ ...toOffset !== void 0 ? { toOffset } : {},
304
+ ...optionalStringProperty(body, "schemaVersion"),
305
+ signal: request.signal
306
+ });
307
+ return json(result, 200, options);
308
+ }
309
+ const widgetSubmissionMatch = path.match(/^\/conversations\/([^/]+)\/widgets\/([^/]+)\/submissions$/);
310
+ if (request.method === "POST" && widgetSubmissionMatch) {
311
+ if (!options.runtime.submitWidget) return json({ error: "Widget submissions are not supported by this runtime" }, 501, options);
312
+ const conversationId = decodeURIComponent(widgetSubmissionMatch[1] ?? "");
313
+ const promptId = decodeURIComponent(widgetSubmissionMatch[2] ?? "");
314
+ const body = await readObject(request);
315
+ const widgetKind = optionalString(body, "widgetKind");
316
+ if (!widgetKind) return json({ error: "widgetKind is required" }, 400, options);
317
+ const event = await options.runtime.submitWidget({
318
+ conversationId,
319
+ promptId,
320
+ widgetKind,
321
+ output: body.output
322
+ });
323
+ return json({ event }, 200, options);
324
+ }
325
+ const snapshotMatch = path.match(/^\/conversations\/([^/]+)\/snapshot$/);
326
+ if (request.method === "GET" && snapshotMatch) {
327
+ if (!options.runtime.getSnapshot) return json({ error: "Snapshots are not supported by this runtime" }, 501, options);
328
+ const conversationId = decodeURIComponent(snapshotMatch[1] ?? "");
329
+ const snapshot = await options.runtime.getSnapshot(conversationId);
330
+ return json({ snapshot }, 200, options);
331
+ }
332
+ const replayMatch = path.match(/^\/conversations\/([^/]+)\/replay$/);
333
+ if (request.method === "GET" && replayMatch) {
334
+ if (!options.runtime.replayConversation) return json({ error: "Event replay is not supported by this runtime" }, 501, options);
335
+ const conversationId = decodeURIComponent(replayMatch[1] ?? "");
336
+ const afterOffset = parseOptionalInteger(url.searchParams.get("after"));
337
+ const replay = await options.runtime.replayConversation({
338
+ conversationId,
339
+ ...afterOffset !== void 0 ? { afterOffset } : {}
340
+ });
341
+ return json(replay, 200, options);
342
+ }
343
+ const eventsMatch = path.match(/^\/conversations\/([^/]+)\/events$/);
344
+ if (request.method === "GET" && eventsMatch) {
345
+ const conversationId = decodeURIComponent(eventsMatch[1] ?? "");
346
+ const afterOffset = parseOptionalInteger(url.searchParams.get("after"));
347
+ const events = await options.runtime.listEvents(conversationId, afterOffset);
348
+ return json({ events }, 200, options);
349
+ }
350
+ const streamMatch = path.match(/^\/conversations\/([^/]+)\/events\/stream$/);
351
+ if (request.method === "GET" && streamMatch) {
352
+ const conversationId = decodeURIComponent(streamMatch[1] ?? "");
353
+ const afterOffset = parseOptionalInteger(url.searchParams.get("after"));
354
+ return streamEvents({
355
+ runtime: options.runtime,
356
+ conversationId,
357
+ afterOffset,
358
+ pollIntervalMs,
359
+ signal: request.signal,
360
+ responseOptions: options
361
+ });
362
+ }
363
+ return json({ error: "Not found" }, 404, options);
364
+ } catch (error) {
365
+ if (error instanceof HttpInputError) {
366
+ return json({ error: error.message }, error.status, options);
367
+ }
368
+ return json({
369
+ error: error instanceof Error ? error.message : "Unknown error"
370
+ }, 500, options);
371
+ }
372
+ }
373
+ };
374
+ }
375
+ async function readObject(request) {
376
+ const body = await readJson(request);
377
+ if (!isRecord(body)) throw new HttpInputError("Request body must be a JSON object.");
378
+ return body;
379
+ }
380
+ function optionalString(body, key) {
381
+ const value = body[key];
382
+ if (value === void 0 || value === null) return void 0;
383
+ if (typeof value !== "string") throw new HttpInputError(`${key} must be a string.`);
384
+ const trimmed = value.trim();
385
+ return trimmed.length > 0 ? trimmed : void 0;
386
+ }
387
+ function optionalStringProperty(body, key) {
388
+ const value = optionalString(body, key);
389
+ return value ? { [key]: value } : {};
390
+ }
391
+ function optionalNonNegativeNumber(body, key) {
392
+ const value = body[key];
393
+ if (value === void 0 || value === null) return void 0;
394
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
395
+ throw new HttpInputError(`${key} must be a non-negative integer.`);
396
+ }
397
+ return value;
398
+ }
399
+ function optionalRouting(body, key) {
400
+ const value = optionalString(body, key);
401
+ if (!value) return void 0;
402
+ if (value !== "none" && value !== "activeJourneyOnly" && value !== "full" && value !== "targeted") {
403
+ throw new HttpInputError(`${key} must be a valid routing mode.`);
404
+ }
405
+ return value;
406
+ }
407
+ function optionalTarget(body, key) {
408
+ const value = body[key];
409
+ if (value === void 0 || value === null) return void 0;
410
+ if (!isRecord(value)) throw new HttpInputError(`${key} must be an object.`);
411
+ const journeyId = optionalString(value, "journeyId");
412
+ const stateId = optionalString(value, "stateId");
413
+ return {
414
+ ...journeyId ? { journeyId } : {},
415
+ ...stateId ? { stateId } : {}
416
+ };
417
+ }
418
+ function optionalVoiceClient(body) {
419
+ const value = body.client;
420
+ if (value === void 0 || value === null) return {};
421
+ if (!isRecord(value)) throw new HttpInputError("client must be an object.");
422
+ const userAgent = optionalString(value, "userAgent");
423
+ const locale = optionalString(value, "locale");
424
+ const metadata = value.metadata;
425
+ if (metadata !== void 0 && metadata !== null && !isRecord(metadata)) {
426
+ throw new HttpInputError("client.metadata must be an object.");
427
+ }
428
+ return {
429
+ client: {
430
+ ...userAgent ? { userAgent } : {},
431
+ ...locale ? { locale } : {},
432
+ ...isRecord(metadata) ? { metadata } : {}
433
+ }
434
+ };
435
+ }
436
+ function withVoiceEventsUrl(result, basePath) {
437
+ return {
438
+ ...result,
439
+ eventsUrl: `${basePath}/conversations/${encodeURIComponent(result.conversation.id)}/events/stream`
440
+ };
441
+ }
442
+ function isRecord(value) {
443
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
444
+ }
445
+ export {
446
+ createCognideskHttpHandler
447
+ };
448
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/responses.ts","../src/path.ts","../src/sse.ts","../src/handler.ts"],"sourcesContent":["export interface ResponseOptions {\n cors?: boolean;\n}\n\nexport class HttpInputError extends Error {\n readonly status = 400;\n}\n\nexport async function readJson<T = unknown>(request: Request): Promise<T> {\n if (!request.body) return {} as T;\n try {\n return await request.json() as T;\n } catch {\n throw new HttpInputError(\"Request body must be valid JSON.\");\n }\n}\n\nexport function json(body: unknown, status: number, options: ResponseOptions) {\n return new Response(JSON.stringify(body), {\n status,\n headers: withCors({\n \"content-type\": \"application/json; charset=utf-8\",\n }, options),\n });\n}\n\nexport function emptyResponse(status: number, options: ResponseOptions) {\n return new Response(null, {\n status,\n headers: withCors({}, options),\n });\n}\n\nexport function withCors(headers: Record<string, string>, options: ResponseOptions) {\n if (!options.cors) return headers;\n return {\n ...headers,\n \"access-control-allow-origin\": \"*\",\n \"access-control-allow-methods\": \"GET,POST,OPTIONS\",\n \"access-control-allow-headers\": \"content-type,authorization\",\n };\n}\n","export function normalizeBasePath(basePath: string) {\n if (!basePath || basePath === \"/\") return \"\";\n return basePath.startsWith(\"/\") ? basePath.replace(/\\/$/, \"\") : `/${basePath.replace(/\\/$/, \"\")}`;\n}\n\nexport function stripBasePath(pathname: string, basePath: string) {\n if (!basePath) return pathname;\n if (pathname === basePath) return \"/\";\n if (!pathname.startsWith(`${basePath}/`)) return null;\n return pathname.slice(basePath.length);\n}\n\nexport function parseOptionalInteger(value: string | null) {\n if (value === null || value === \"\") return undefined;\n if (!/^(0|[1-9]\\d*)$/.test(value)) {\n throw new HttpInputError(\"after must be a non-negative integer.\");\n }\n return Number(value);\n}\nimport { HttpInputError } from \"./responses.js\";\n","import type { CognideskRuntime, RuntimeEvent } from \"@cognidesk/core\";\nimport { withCors, type ResponseOptions } from \"./responses.js\";\n\nexport interface EventStreamRuntime {\n listEvents(conversationId: string, afterOffset?: number): Promise<RuntimeEvent[]>;\n}\n\nexport function streamEvents(options: {\n runtime: EventStreamRuntime | CognideskRuntime;\n conversationId: string;\n afterOffset: number | undefined;\n pollIntervalMs: number;\n signal: AbortSignal;\n responseOptions: ResponseOptions;\n}) {\n const encoder = new TextEncoder();\n let offset = options.afterOffset ?? 0;\n let closed = false;\n const stream = new ReadableStream<Uint8Array>({\n start(controller) {\n const close = () => {\n if (closed) return;\n closed = true;\n try {\n controller.close();\n } catch {\n // The stream may already have been closed by cancel().\n }\n };\n options.signal.addEventListener(\"abort\", close, { once: true });\n\n const poll = async () => {\n if (closed) return;\n try {\n const events = await options.runtime.listEvents(options.conversationId, offset);\n if (closed) return;\n for (const event of events) {\n if (closed) return;\n offset = event.offset;\n controller.enqueue(encoder.encode(formatSseEvent(event)));\n }\n } catch (error) {\n if (closed) return;\n controller.enqueue(encoder.encode(formatSseError(error)));\n }\n if (!closed) setTimeout(poll, options.pollIntervalMs);\n };\n\n if (!closed) controller.enqueue(encoder.encode(\": cognidesk stream ready\\n\\n\"));\n void poll();\n },\n cancel() {\n closed = true;\n },\n });\n\n return new Response(stream, {\n status: 200,\n headers: withCors({\n \"content-type\": \"text/event-stream; charset=utf-8\",\n \"cache-control\": \"no-cache, no-transform\",\n connection: \"keep-alive\",\n }, options.responseOptions),\n });\n}\n\nfunction formatSseEvent(event: RuntimeEvent) {\n return [\n `id: ${event.offset}`,\n \"event: event\",\n `data: ${JSON.stringify(event)}`,\n \"\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction formatSseError(error: unknown) {\n return [\n \"event: error\",\n `data: ${JSON.stringify({ error: error instanceof Error ? error.message : \"Unknown error\" })}`,\n \"\",\n \"\",\n ].join(\"\\n\");\n}\n","import { parseOptionalInteger, normalizeBasePath, stripBasePath } from \"./path.js\";\nimport { emptyResponse, HttpInputError, json, readJson } from \"./responses.js\";\nimport { streamEvents } from \"./sse.js\";\nimport type {\n CognideskHttpHandler,\n CognideskHttpHandlerOptions,\n CreateCloseBody,\n CreateCompactionBody,\n CreateConversationBody,\n CreateGeneratedPreambleBody,\n CreateHandoffBody,\n CreateIntermediateMessageBody,\n CreateJourneyEventBody,\n CreateMessageBody,\n CreateResumeBody,\n CreateRuntimeEventBody,\n CreateWidgetSubmissionBody,\n} from \"./types.js\";\n\nexport function createCognideskHttpHandler(options: CognideskHttpHandlerOptions): CognideskHttpHandler {\n const basePath = normalizeBasePath(options.basePath ?? \"\");\n const pollIntervalMs = options.ssePollIntervalMs ?? 500;\n\n return {\n async handle(request) {\n if (request.method === \"OPTIONS\" && options.cors) {\n return emptyResponse(204, options);\n }\n\n try {\n const url = new URL(request.url);\n const path = stripBasePath(url.pathname, basePath);\n if (path === null) return json({ error: \"Not found\" }, 404, options);\n\n if (request.method === \"POST\" && path === \"/conversations\") {\n const body = await readObject(request);\n const agentId = optionalString(body, \"agentId\") ?? options.agentId;\n if (!agentId) return json({ error: \"agentId is required\" }, 400, options);\n const conversation = await options.runtime.createConversation({\n ...optionalStringProperty(body, \"id\"),\n agentId,\n context: body.context ?? {},\n });\n return json({ conversation }, 201, options);\n }\n\n if (request.method === \"POST\" && path === \"/voice/conversations\") {\n if (!options.runtime.startVoiceConversation) return json({ error: \"Voice conversations are not supported by this runtime\" }, 501, options);\n if (!options.voice?.createSocket) return json({ error: \"Voice socket handshakes are not configured\" }, 501, options);\n const body = await readObject(request);\n const agentId = optionalString(body, \"agentId\") ?? options.agentId;\n if (!agentId) return json({ error: \"agentId is required\" }, 400, options);\n const result = await options.runtime.startVoiceConversation({\n ...optionalStringProperty(body, \"id\"),\n agentId,\n context: body.context ?? {},\n ...optionalVoiceClient(body),\n ...(body.app !== undefined ? { app: body.app } : {}),\n });\n const socket = await options.voice.createSocket({ result, request, basePath });\n return json(withVoiceEventsUrl({ ...result, socket }, basePath), 201, options);\n }\n\n const voiceSegmentMatch = path.match(/^\\/conversations\\/([^/]+)\\/voice-segments$/);\n if (request.method === \"POST\" && voiceSegmentMatch) {\n if (!options.runtime.startVoiceSegment) return json({ error: \"Voice segments are not supported by this runtime\" }, 501, options);\n if (!options.voice?.createSocket) return json({ error: \"Voice socket handshakes are not configured\" }, 501, options);\n const conversationId = decodeURIComponent(voiceSegmentMatch[1] ?? \"\");\n const body = await readObject(request);\n const result = await options.runtime.startVoiceSegment({\n conversationId,\n ...optionalVoiceClient(body),\n ...(body.app !== undefined ? { app: body.app } : {}),\n });\n const socket = await options.voice.createSocket({ result, request, basePath });\n return json(withVoiceEventsUrl({ ...result, socket }, basePath), 200, options);\n }\n\n const messageMatch = path.match(/^\\/conversations\\/([^/]+)\\/messages$/);\n if (request.method === \"POST\" && messageMatch) {\n const conversationId = decodeURIComponent(messageMatch[1] ?? \"\");\n const body = await readObject(request);\n const text = optionalString(body, \"text\") ?? optionalString(body, \"message\");\n if (!text) return json({ error: \"message is required\" }, 400, options);\n const result = await options.runtime.handleUserMessage({\n conversationId,\n text,\n ...(body.turn !== undefined ? { turn: body.turn } : {}),\n ...(body.app !== undefined ? { app: body.app } : {}),\n signal: request.signal,\n });\n return json(result, 200, options);\n }\n\n const customEventMatch = path.match(/^\\/conversations\\/([^/]+)\\/custom-events\\/([^/]+)$/);\n if (request.method === \"POST\" && customEventMatch) {\n if (!options.runtime.emitCustomEvent) return json({ error: \"Custom events are not supported by this runtime\" }, 501, options);\n const conversationId = decodeURIComponent(customEventMatch[1] ?? \"\");\n const eventName = decodeURIComponent(customEventMatch[2] ?? \"\");\n const event = options.customEvents?.find((candidate) => candidate.name === eventName);\n if (!event) return json({ error: `Custom event '${eventName}' is not registered with the HTTP handler` }, 404, options);\n const body = await readObject(request);\n const emitted = await options.runtime.emitCustomEvent({\n conversationId,\n event,\n payload: body.payload,\n });\n return json({ event: emitted }, 200, options);\n }\n\n const journeyEventMatch = path.match(/^\\/conversations\\/([^/]+)\\/journey-events\\/([^/]+)$/);\n if (request.method === \"POST\" && journeyEventMatch) {\n if (!options.runtime.emitJourneyEvent) return json({ error: \"Journey events are not supported by this runtime\" }, 501, options);\n const conversationId = decodeURIComponent(journeyEventMatch[1] ?? \"\");\n const eventName = decodeURIComponent(journeyEventMatch[2] ?? \"\");\n const event = options.journeyEvents?.find((candidate) => candidate.name === eventName);\n if (!event) return json({ error: `Journey event '${eventName}' is not registered with the HTTP handler` }, 404, options);\n const body = await readObject(request);\n const routing = optionalRouting(body, \"routing\");\n const target = optionalTarget(body, \"target\");\n const result = await options.runtime.emitJourneyEvent({\n conversationId,\n event,\n payload: body.payload,\n ...(routing ? { routing } : {}),\n ...(target ? { target } : {}),\n ...(body.app !== undefined ? { app: body.app } : {}),\n signal: request.signal,\n });\n return json(result, 200, options);\n }\n\n const handoffMatch = path.match(/^\\/conversations\\/([^/]+)\\/handoff$/);\n if (request.method === \"POST\" && handoffMatch) {\n if (!options.runtime.requestHandoff) return json({ error: \"Handoff is not supported by this runtime\" }, 501, options);\n const conversationId = decodeURIComponent(handoffMatch[1] ?? \"\");\n const body = await readObject(request);\n const reason = optionalString(body, \"reason\");\n if (!reason) return json({ error: \"reason is required\" }, 400, options);\n const result = await options.runtime.requestHandoff({\n conversationId,\n reason,\n ...optionalStringProperty(body, \"summary\"),\n ...(body.payload !== undefined ? { payload: body.payload } : {}),\n });\n return json(result, 200, options);\n }\n\n const closeMatch = path.match(/^\\/conversations\\/([^/]+)\\/close$/);\n if (request.method === \"POST\" && closeMatch) {\n if (!options.runtime.closeConversation) return json({ error: \"Conversation closure is not supported by this runtime\" }, 501, options);\n const conversationId = decodeURIComponent(closeMatch[1] ?? \"\");\n const body = await readObject(request);\n const conversation = await options.runtime.closeConversation(\n conversationId,\n optionalString(body, \"reason\"),\n );\n return json({ conversation }, 200, options);\n }\n\n const resumeMatch = path.match(/^\\/conversations\\/([^/]+)\\/resume$/);\n if (request.method === \"POST\" && resumeMatch) {\n if (!options.runtime.resumeConversation) return json({ error: \"Conversation resume is not supported by this runtime\" }, 501, options);\n const conversationId = decodeURIComponent(resumeMatch[1] ?? \"\");\n const body = await readObject(request);\n const result = await options.runtime.resumeConversation({\n conversationId,\n ...optionalStringProperty(body, \"reason\"),\n ...(body.payload !== undefined ? { payload: body.payload } : {}),\n });\n return json(result, 200, options);\n }\n\n const intermediateMessageMatch = path.match(/^\\/conversations\\/([^/]+)\\/intermediate-messages$/);\n if (request.method === \"POST\" && intermediateMessageMatch) {\n if (!options.runtime.emitIntermediateMessage) return json({ error: \"Intermediate messages are not supported by this runtime\" }, 501, options);\n const conversationId = decodeURIComponent(intermediateMessageMatch[1] ?? \"\");\n const body = await readObject(request);\n const text = optionalString(body, \"text\");\n if (!text) return json({ error: \"text is required\" }, 400, options);\n const result = await options.runtime.emitIntermediateMessage({\n conversationId,\n text,\n ...(body.visibleToModel === true ? { visibleToModel: true } : {}),\n });\n return json(result, 200, options);\n }\n\n const preambleMatch = path.match(/^\\/conversations\\/([^/]+)\\/preambles$/);\n if (request.method === \"POST\" && preambleMatch) {\n if (!options.runtime.emitGeneratedPreamble) return json({ error: \"Generated preambles are not supported by this runtime\" }, 501, options);\n const conversationId = decodeURIComponent(preambleMatch[1] ?? \"\");\n const body = await readObject(request);\n const maxWords = optionalNonNegativeNumber(body, \"maxWords\");\n const result = await options.runtime.emitGeneratedPreamble({\n conversationId,\n ...optionalStringProperty(body, \"purpose\"),\n ...(maxWords !== undefined ? { maxWords } : {}),\n signal: request.signal,\n });\n return json(result, 200, options);\n }\n\n const compactionMatch = path.match(/^\\/conversations\\/([^/]+)\\/compact$/);\n if (request.method === \"POST\" && compactionMatch) {\n if (!options.runtime.compactConversation) return json({ error: \"Conversation compaction is not supported by this runtime\" }, 501, options);\n const conversationId = decodeURIComponent(compactionMatch[1] ?? \"\");\n const body = await readObject(request);\n const fromOffset = optionalNonNegativeNumber(body, \"fromOffset\");\n const toOffset = optionalNonNegativeNumber(body, \"toOffset\");\n const result = await options.runtime.compactConversation({\n conversationId,\n ...(fromOffset !== undefined ? { fromOffset } : {}),\n ...(toOffset !== undefined ? { toOffset } : {}),\n ...optionalStringProperty(body, \"schemaVersion\"),\n signal: request.signal,\n });\n return json(result, 200, options);\n }\n\n const widgetSubmissionMatch = path.match(/^\\/conversations\\/([^/]+)\\/widgets\\/([^/]+)\\/submissions$/);\n if (request.method === \"POST\" && widgetSubmissionMatch) {\n if (!options.runtime.submitWidget) return json({ error: \"Widget submissions are not supported by this runtime\" }, 501, options);\n const conversationId = decodeURIComponent(widgetSubmissionMatch[1] ?? \"\");\n const promptId = decodeURIComponent(widgetSubmissionMatch[2] ?? \"\");\n const body = await readObject(request);\n const widgetKind = optionalString(body, \"widgetKind\");\n if (!widgetKind) return json({ error: \"widgetKind is required\" }, 400, options);\n const event = await options.runtime.submitWidget({\n conversationId,\n promptId,\n widgetKind,\n output: body.output,\n });\n return json({ event }, 200, options);\n }\n\n const snapshotMatch = path.match(/^\\/conversations\\/([^/]+)\\/snapshot$/);\n if (request.method === \"GET\" && snapshotMatch) {\n if (!options.runtime.getSnapshot) return json({ error: \"Snapshots are not supported by this runtime\" }, 501, options);\n const conversationId = decodeURIComponent(snapshotMatch[1] ?? \"\");\n const snapshot = await options.runtime.getSnapshot(conversationId);\n return json({ snapshot }, 200, options);\n }\n\n const replayMatch = path.match(/^\\/conversations\\/([^/]+)\\/replay$/);\n if (request.method === \"GET\" && replayMatch) {\n if (!options.runtime.replayConversation) return json({ error: \"Event replay is not supported by this runtime\" }, 501, options);\n const conversationId = decodeURIComponent(replayMatch[1] ?? \"\");\n const afterOffset = parseOptionalInteger(url.searchParams.get(\"after\"));\n const replay = await options.runtime.replayConversation({\n conversationId,\n ...(afterOffset !== undefined ? { afterOffset } : {}),\n });\n return json(replay, 200, options);\n }\n\n const eventsMatch = path.match(/^\\/conversations\\/([^/]+)\\/events$/);\n if (request.method === \"GET\" && eventsMatch) {\n const conversationId = decodeURIComponent(eventsMatch[1] ?? \"\");\n const afterOffset = parseOptionalInteger(url.searchParams.get(\"after\"));\n const events = await options.runtime.listEvents(conversationId, afterOffset);\n return json({ events }, 200, options);\n }\n\n const streamMatch = path.match(/^\\/conversations\\/([^/]+)\\/events\\/stream$/);\n if (request.method === \"GET\" && streamMatch) {\n const conversationId = decodeURIComponent(streamMatch[1] ?? \"\");\n const afterOffset = parseOptionalInteger(url.searchParams.get(\"after\"));\n return streamEvents({\n runtime: options.runtime,\n conversationId,\n afterOffset,\n pollIntervalMs,\n signal: request.signal,\n responseOptions: options,\n });\n }\n\n return json({ error: \"Not found\" }, 404, options);\n } catch (error) {\n if (error instanceof HttpInputError) {\n return json({ error: error.message }, error.status, options);\n }\n return json({\n error: error instanceof Error ? error.message : \"Unknown error\",\n }, 500, options);\n }\n },\n };\n}\n\nasync function readObject(request: Request) {\n const body = await readJson(request);\n if (!isRecord(body)) throw new HttpInputError(\"Request body must be a JSON object.\");\n return body;\n}\n\nfunction optionalString(body: Record<string, unknown>, key: string) {\n const value = body[key];\n if (value === undefined || value === null) return undefined;\n if (typeof value !== \"string\") throw new HttpInputError(`${key} must be a string.`);\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction optionalStringProperty<TKey extends string>(body: Record<string, unknown>, key: TKey) {\n const value = optionalString(body, key);\n return value ? { [key]: value } as Record<TKey, string> : {};\n}\n\nfunction optionalNonNegativeNumber(body: Record<string, unknown>, key: string) {\n const value = body[key];\n if (value === undefined || value === null) return undefined;\n if (typeof value !== \"number\" || !Number.isSafeInteger(value) || value < 0) {\n throw new HttpInputError(`${key} must be a non-negative integer.`);\n }\n return value;\n}\n\nfunction optionalRouting(body: Record<string, unknown>, key: string) {\n const value = optionalString(body, key);\n if (!value) return undefined;\n if (value !== \"none\" && value !== \"activeJourneyOnly\" && value !== \"full\" && value !== \"targeted\") {\n throw new HttpInputError(`${key} must be a valid routing mode.`);\n }\n return value;\n}\n\nfunction optionalTarget(body: Record<string, unknown>, key: string) {\n const value = body[key];\n if (value === undefined || value === null) return undefined;\n if (!isRecord(value)) throw new HttpInputError(`${key} must be an object.`);\n const journeyId = optionalString(value, \"journeyId\");\n const stateId = optionalString(value, \"stateId\");\n return {\n ...(journeyId ? { journeyId } : {}),\n ...(stateId ? { stateId } : {}),\n };\n}\n\nfunction optionalVoiceClient(body: Record<string, unknown>) {\n const value = body.client;\n if (value === undefined || value === null) return {};\n if (!isRecord(value)) throw new HttpInputError(\"client must be an object.\");\n const userAgent = optionalString(value, \"userAgent\");\n const locale = optionalString(value, \"locale\");\n const metadata = value.metadata;\n if (metadata !== undefined && metadata !== null && !isRecord(metadata)) {\n throw new HttpInputError(\"client.metadata must be an object.\");\n }\n return {\n client: {\n ...(userAgent ? { userAgent } : {}),\n ...(locale ? { locale } : {}),\n ...(isRecord(metadata) ? { metadata } : {}),\n },\n };\n}\n\nfunction withVoiceEventsUrl<T extends { conversation: { id: string } }>(result: T, basePath: string) {\n return {\n ...result,\n eventsUrl: `${basePath}/conversations/${encodeURIComponent(result.conversation.id)}/events/stream`,\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value && typeof value === \"object\" && !Array.isArray(value));\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@cognidesk/http",
3
+ "version": "0.0.1",
4
+ "license": "Apache-2.0",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "tsup src/index.ts --format esm --dts --sourcemap",
16
+ "typecheck": "tsc -p tsconfig.json --noEmit",
17
+ "test": "vitest run --passWithNoTests",
18
+ "lint": "tsc -p tsconfig.json --noEmit"
19
+ },
20
+ "dependencies": {
21
+ "@cognidesk/core": "0.0.1"
22
+ },
23
+ "devDependencies": {
24
+ "tsup": "^8.5.0",
25
+ "typescript": "^5.9.3",
26
+ "vitest": "^4.0.14"
27
+ },
28
+ "publishConfig": {
29
+ "access": "public",
30
+ "registry": "https://registry.npmjs.org/"
31
+ },
32
+ "files": [
33
+ "dist"
34
+ ]
35
+ }