@copilotkitnext/runtime 0.0.19 → 0.0.21-alpha.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/index.mjs CHANGED
@@ -1,836 +1,24 @@
1
- // package.json
2
- var package_default = {
3
- name: "@copilotkitnext/runtime",
4
- version: "0.0.19",
5
- description: "Server-side runtime package for CopilotKit2",
6
- main: "dist/index.js",
7
- types: "dist/index.d.ts",
8
- exports: {
9
- ".": {
10
- types: "./dist/index.d.ts",
11
- import: "./dist/index.mjs",
12
- require: "./dist/index.js"
13
- }
14
- },
15
- publishConfig: {
16
- access: "public"
17
- },
18
- scripts: {
19
- build: "tsup",
20
- prepublishOnly: "pnpm run build",
21
- dev: "tsup --watch",
22
- lint: "eslint . --max-warnings 0",
23
- "check-types": "tsc --noEmit",
24
- clean: "rm -rf dist",
25
- test: "vitest run",
26
- "test:watch": "vitest",
27
- "test:coverage": "vitest run --coverage"
28
- },
29
- devDependencies: {
30
- "@copilotkitnext/eslint-config": "workspace:*",
31
- "@copilotkitnext/typescript-config": "workspace:*",
32
- "@types/node": "^22.15.3",
33
- eslint: "^9.30.0",
34
- openai: "^5.9.0",
35
- tsup: "^8.5.0",
36
- typescript: "5.8.2",
37
- vitest: "^3.0.5"
38
- },
39
- dependencies: {
40
- "@ag-ui/client": "0.0.40-alpha.6",
41
- "@ag-ui/core": "0.0.40-alpha.6",
42
- "@ag-ui/encoder": "0.0.40-alpha.6",
43
- "@copilotkitnext/shared": "workspace:*",
44
- hono: "^4.6.13",
45
- rxjs: "7.8.1"
46
- },
47
- peerDependencies: {
48
- openai: "^5.9.0"
49
- },
50
- peerDependenciesMeta: {},
51
- engines: {
52
- node: ">=18"
53
- }
54
- };
55
-
56
- // src/runner/agent-runner.ts
57
- var AgentRunner = class {
58
- };
59
-
60
- // src/runner/in-memory.ts
61
- import { ReplaySubject } from "rxjs";
62
1
  import {
63
- EventType,
64
- compactEvents
65
- } from "@ag-ui/client";
66
- import { finalizeRunEvents } from "@copilotkitnext/shared";
67
- var InMemoryEventStore = class {
68
- constructor(threadId) {
69
- this.threadId = threadId;
70
- }
71
- /** The subject that current consumers subscribe to. */
72
- subject = null;
73
- /** True while a run is actively producing events. */
74
- isRunning = false;
75
- /** Current run ID */
76
- currentRunId = null;
77
- /** Historic completed runs */
78
- historicRuns = [];
79
- /** Currently running agent instance (if any). */
80
- agent = null;
81
- /** Subject returned from run() while the run is active. */
82
- runSubject = null;
83
- /** True once stop() has been requested but the run has not yet finalized. */
84
- stopRequested = false;
85
- /** Reference to the events emitted in the current run. */
86
- currentEvents = null;
87
- };
88
- var GLOBAL_STORE = /* @__PURE__ */ new Map();
89
- var InMemoryAgentRunner = class extends AgentRunner {
90
- run(request) {
91
- let existingStore = GLOBAL_STORE.get(request.threadId);
92
- if (!existingStore) {
93
- existingStore = new InMemoryEventStore(request.threadId);
94
- GLOBAL_STORE.set(request.threadId, existingStore);
95
- }
96
- const store = existingStore;
97
- if (store.isRunning) {
98
- throw new Error("Thread already running");
99
- }
100
- store.isRunning = true;
101
- store.currentRunId = request.input.runId;
102
- store.agent = request.agent;
103
- store.stopRequested = false;
104
- const seenMessageIds = /* @__PURE__ */ new Set();
105
- const currentRunEvents = [];
106
- store.currentEvents = currentRunEvents;
107
- const historicMessageIds = /* @__PURE__ */ new Set();
108
- for (const run of store.historicRuns) {
109
- for (const event of run.events) {
110
- if ("messageId" in event && typeof event.messageId === "string") {
111
- historicMessageIds.add(event.messageId);
112
- }
113
- if (event.type === EventType.RUN_STARTED) {
114
- const runStarted = event;
115
- const messages = runStarted.input?.messages ?? [];
116
- for (const message of messages) {
117
- historicMessageIds.add(message.id);
118
- }
119
- }
120
- }
121
- }
122
- const nextSubject = new ReplaySubject(Infinity);
123
- const prevSubject = store.subject;
124
- store.subject = nextSubject;
125
- const runSubject = new ReplaySubject(Infinity);
126
- store.runSubject = runSubject;
127
- const runAgent = async () => {
128
- const lastRun = store.historicRuns[store.historicRuns.length - 1];
129
- const parentRunId = lastRun?.runId ?? null;
130
- try {
131
- await request.agent.runAgent(request.input, {
132
- onEvent: ({ event }) => {
133
- let processedEvent = event;
134
- if (event.type === EventType.RUN_STARTED) {
135
- const runStartedEvent = event;
136
- if (!runStartedEvent.input) {
137
- const sanitizedMessages = request.input.messages ? request.input.messages.filter(
138
- (message) => !historicMessageIds.has(message.id)
139
- ) : void 0;
140
- const updatedInput = {
141
- ...request.input,
142
- ...sanitizedMessages !== void 0 ? { messages: sanitizedMessages } : {}
143
- };
144
- processedEvent = {
145
- ...runStartedEvent,
146
- input: updatedInput
147
- };
148
- }
149
- }
150
- runSubject.next(processedEvent);
151
- nextSubject.next(processedEvent);
152
- currentRunEvents.push(processedEvent);
153
- },
154
- onNewMessage: ({ message }) => {
155
- if (!seenMessageIds.has(message.id)) {
156
- seenMessageIds.add(message.id);
157
- }
158
- },
159
- onRunStartedEvent: () => {
160
- if (request.input.messages) {
161
- for (const message of request.input.messages) {
162
- if (!seenMessageIds.has(message.id)) {
163
- seenMessageIds.add(message.id);
164
- }
165
- }
166
- }
167
- }
168
- });
169
- const appendedEvents = finalizeRunEvents(currentRunEvents, {
170
- stopRequested: store.stopRequested
171
- });
172
- for (const event of appendedEvents) {
173
- runSubject.next(event);
174
- nextSubject.next(event);
175
- }
176
- if (store.currentRunId) {
177
- const compactedEvents = compactEvents(currentRunEvents);
178
- store.historicRuns.push({
179
- threadId: request.threadId,
180
- runId: store.currentRunId,
181
- parentRunId,
182
- events: compactedEvents,
183
- createdAt: Date.now()
184
- });
185
- }
186
- store.currentEvents = null;
187
- store.currentRunId = null;
188
- store.agent = null;
189
- store.runSubject = null;
190
- store.stopRequested = false;
191
- store.isRunning = false;
192
- runSubject.complete();
193
- nextSubject.complete();
194
- } catch {
195
- const appendedEvents = finalizeRunEvents(currentRunEvents, {
196
- stopRequested: store.stopRequested
197
- });
198
- for (const event of appendedEvents) {
199
- runSubject.next(event);
200
- nextSubject.next(event);
201
- }
202
- if (store.currentRunId && currentRunEvents.length > 0) {
203
- const compactedEvents = compactEvents(currentRunEvents);
204
- store.historicRuns.push({
205
- threadId: request.threadId,
206
- runId: store.currentRunId,
207
- parentRunId,
208
- events: compactedEvents,
209
- createdAt: Date.now()
210
- });
211
- }
212
- store.currentEvents = null;
213
- store.currentRunId = null;
214
- store.agent = null;
215
- store.runSubject = null;
216
- store.stopRequested = false;
217
- store.isRunning = false;
218
- runSubject.complete();
219
- nextSubject.complete();
220
- }
221
- };
222
- if (prevSubject) {
223
- prevSubject.subscribe({
224
- next: (e) => nextSubject.next(e),
225
- error: (err) => nextSubject.error(err),
226
- complete: () => {
227
- }
228
- });
229
- }
230
- runAgent();
231
- return runSubject.asObservable();
232
- }
233
- connect(request) {
234
- const store = GLOBAL_STORE.get(request.threadId);
235
- const connectionSubject = new ReplaySubject(Infinity);
236
- if (!store) {
237
- connectionSubject.complete();
238
- return connectionSubject.asObservable();
239
- }
240
- const allHistoricEvents = [];
241
- for (const run of store.historicRuns) {
242
- allHistoricEvents.push(...run.events);
243
- }
244
- const compactedEvents = compactEvents(allHistoricEvents);
245
- const emittedMessageIds = /* @__PURE__ */ new Set();
246
- for (const event of compactedEvents) {
247
- connectionSubject.next(event);
248
- if ("messageId" in event && typeof event.messageId === "string") {
249
- emittedMessageIds.add(event.messageId);
250
- }
251
- }
252
- if (store.subject && (store.isRunning || store.stopRequested)) {
253
- store.subject.subscribe({
254
- next: (event) => {
255
- if ("messageId" in event && typeof event.messageId === "string" && emittedMessageIds.has(event.messageId)) {
256
- return;
257
- }
258
- connectionSubject.next(event);
259
- },
260
- complete: () => connectionSubject.complete(),
261
- error: (err) => connectionSubject.error(err)
262
- });
263
- } else {
264
- connectionSubject.complete();
265
- }
266
- return connectionSubject.asObservable();
267
- }
268
- isRunning(request) {
269
- const store = GLOBAL_STORE.get(request.threadId);
270
- return Promise.resolve(store?.isRunning ?? false);
271
- }
272
- stop(request) {
273
- const store = GLOBAL_STORE.get(request.threadId);
274
- if (!store || !store.isRunning) {
275
- return Promise.resolve(false);
276
- }
277
- if (store.stopRequested) {
278
- return Promise.resolve(false);
279
- }
280
- store.stopRequested = true;
281
- store.isRunning = false;
282
- const agent = store.agent;
283
- if (!agent) {
284
- store.stopRequested = false;
285
- store.isRunning = false;
286
- return Promise.resolve(false);
287
- }
288
- try {
289
- agent.abortRun();
290
- return Promise.resolve(true);
291
- } catch (error) {
292
- console.error("Failed to abort agent run", error);
293
- store.stopRequested = false;
294
- store.isRunning = true;
295
- return Promise.resolve(false);
296
- }
297
- }
298
- };
299
-
300
- // src/runtime.ts
301
- var VERSION = package_default.version;
302
- var CopilotRuntime = class {
303
- agents;
304
- transcriptionService;
305
- beforeRequestMiddleware;
306
- afterRequestMiddleware;
307
- runner;
308
- constructor({
309
- agents,
310
- transcriptionService,
311
- beforeRequestMiddleware,
312
- afterRequestMiddleware,
313
- runner
314
- }) {
315
- this.agents = agents;
316
- this.transcriptionService = transcriptionService;
317
- this.beforeRequestMiddleware = beforeRequestMiddleware;
318
- this.afterRequestMiddleware = afterRequestMiddleware;
319
- this.runner = runner ?? new InMemoryAgentRunner();
320
- }
321
- };
2
+ AgentRunner,
3
+ CopilotRuntime,
4
+ InMemoryAgentRunner,
5
+ VERSION,
6
+ callAfterRequestMiddleware,
7
+ callBeforeRequestMiddleware,
8
+ createJsonRequest,
9
+ expectString,
10
+ handleConnectAgent,
11
+ handleGetRuntimeInfo,
12
+ handleRunAgent,
13
+ handleStopAgent,
14
+ handleTranscribe,
15
+ parseMethodCall
16
+ } from "./chunk-PBMAFLPB.mjs";
322
17
 
323
- // src/endpoint.ts
18
+ // src/endpoints/hono.ts
324
19
  import { Hono } from "hono";
325
20
  import { cors } from "hono/cors";
326
-
327
- // src/handlers/handle-run.ts
328
- import {
329
- RunAgentInputSchema
330
- } from "@ag-ui/client";
331
- import { EventEncoder } from "@ag-ui/encoder";
332
- async function handleRunAgent({
333
- runtime,
334
- request,
335
- agentId
336
- }) {
337
- try {
338
- const agents = await runtime.agents;
339
- if (!agents[agentId]) {
340
- return new Response(
341
- JSON.stringify({
342
- error: "Agent not found",
343
- message: `Agent '${agentId}' does not exist`
344
- }),
345
- {
346
- status: 404,
347
- headers: { "Content-Type": "application/json" }
348
- }
349
- );
350
- }
351
- const registeredAgent = agents[agentId];
352
- const agent = registeredAgent.clone();
353
- if (agent && "headers" in agent) {
354
- const shouldForward = (headerName) => {
355
- const lower = headerName.toLowerCase();
356
- return lower === "authorization" || lower.startsWith("x-");
357
- };
358
- const forwardableHeaders = {};
359
- request.headers.forEach((value, key) => {
360
- if (shouldForward(key)) {
361
- forwardableHeaders[key] = value;
362
- }
363
- });
364
- agent.headers = {
365
- ...agent.headers,
366
- ...forwardableHeaders
367
- };
368
- }
369
- const stream = new TransformStream();
370
- const writer = stream.writable.getWriter();
371
- const encoder = new EventEncoder();
372
- let streamClosed = false;
373
- (async () => {
374
- let input;
375
- try {
376
- const requestBody = await request.json();
377
- input = RunAgentInputSchema.parse(requestBody);
378
- } catch {
379
- return new Response(
380
- JSON.stringify({
381
- error: "Invalid request body"
382
- }),
383
- { status: 400 }
384
- );
385
- }
386
- agent.setMessages(input.messages);
387
- agent.setState(input.state);
388
- agent.threadId = input.threadId;
389
- runtime.runner.run({
390
- threadId: input.threadId,
391
- agent,
392
- input
393
- }).subscribe({
394
- next: async (event) => {
395
- if (!request.signal.aborted && !streamClosed) {
396
- try {
397
- await writer.write(encoder.encode(event));
398
- } catch (error) {
399
- if (error instanceof Error && error.name === "AbortError") {
400
- streamClosed = true;
401
- }
402
- }
403
- }
404
- },
405
- error: async (error) => {
406
- console.error("Error running agent:", error);
407
- if (!streamClosed) {
408
- try {
409
- await writer.close();
410
- streamClosed = true;
411
- } catch {
412
- }
413
- }
414
- },
415
- complete: async () => {
416
- if (!streamClosed) {
417
- try {
418
- await writer.close();
419
- streamClosed = true;
420
- } catch {
421
- }
422
- }
423
- }
424
- });
425
- })().catch((error) => {
426
- console.error("Error running agent:", error);
427
- console.error(
428
- "Error stack:",
429
- error instanceof Error ? error.stack : "No stack trace"
430
- );
431
- console.error("Error details:", {
432
- name: error instanceof Error ? error.name : "Unknown",
433
- message: error instanceof Error ? error.message : String(error),
434
- cause: error instanceof Error ? error.cause : void 0
435
- });
436
- if (!streamClosed) {
437
- try {
438
- writer.close();
439
- streamClosed = true;
440
- } catch {
441
- }
442
- }
443
- });
444
- return new Response(stream.readable, {
445
- status: 200,
446
- headers: {
447
- "Content-Type": "text/event-stream",
448
- "Cache-Control": "no-cache",
449
- Connection: "keep-alive"
450
- }
451
- });
452
- } catch (error) {
453
- console.error("Error running agent:", error);
454
- console.error(
455
- "Error stack:",
456
- error instanceof Error ? error.stack : "No stack trace"
457
- );
458
- console.error("Error details:", {
459
- name: error instanceof Error ? error.name : "Unknown",
460
- message: error instanceof Error ? error.message : String(error),
461
- cause: error instanceof Error ? error.cause : void 0
462
- });
463
- return new Response(
464
- JSON.stringify({
465
- error: "Failed to run agent",
466
- message: error instanceof Error ? error.message : "Unknown error"
467
- }),
468
- {
469
- status: 500,
470
- headers: { "Content-Type": "application/json" }
471
- }
472
- );
473
- }
474
- }
475
-
476
- // src/handlers/get-runtime-info.ts
477
- async function handleGetRuntimeInfo({
478
- runtime
479
- }) {
480
- try {
481
- const agents = await runtime.agents;
482
- const agentsDict = Object.entries(agents).reduce(
483
- (acc, [name, agent]) => {
484
- acc[name] = {
485
- name,
486
- description: agent.description,
487
- className: agent.constructor.name
488
- };
489
- return acc;
490
- },
491
- {}
492
- );
493
- const runtimeInfo = {
494
- version: VERSION,
495
- agents: agentsDict,
496
- audioFileTranscriptionEnabled: !!runtime.transcriptionService
497
- };
498
- return new Response(JSON.stringify(runtimeInfo), {
499
- status: 200,
500
- headers: { "Content-Type": "application/json" }
501
- });
502
- } catch (error) {
503
- return new Response(
504
- JSON.stringify({
505
- error: "Failed to retrieve runtime information",
506
- message: error instanceof Error ? error.message : "Unknown error"
507
- }),
508
- {
509
- status: 500,
510
- headers: { "Content-Type": "application/json" }
511
- }
512
- );
513
- }
514
- }
515
-
516
- // src/handlers/handle-transcribe.ts
517
- async function handleTranscribe({
518
- runtime,
519
- request
520
- }) {
521
- try {
522
- if (!runtime.transcriptionService) {
523
- return new Response(
524
- JSON.stringify({
525
- error: "Transcription service not configured",
526
- message: "No transcription service has been configured in the runtime"
527
- }),
528
- {
529
- status: 503,
530
- headers: { "Content-Type": "application/json" }
531
- }
532
- );
533
- }
534
- const contentType = request.headers.get("content-type");
535
- if (!contentType || !contentType.includes("multipart/form-data")) {
536
- return new Response(
537
- JSON.stringify({
538
- error: "Invalid content type",
539
- message: "Request must contain multipart/form-data with an audio file"
540
- }),
541
- {
542
- status: 400,
543
- headers: { "Content-Type": "application/json" }
544
- }
545
- );
546
- }
547
- const formData = await request.formData();
548
- const audioFile = formData.get("audio");
549
- if (!audioFile || !(audioFile instanceof File)) {
550
- return new Response(
551
- JSON.stringify({
552
- error: "Missing audio file",
553
- message: "No audio file found in form data. Please include an 'audio' field."
554
- }),
555
- {
556
- status: 400,
557
- headers: { "Content-Type": "application/json" }
558
- }
559
- );
560
- }
561
- const validAudioTypes = [
562
- "audio/mpeg",
563
- "audio/mp3",
564
- "audio/mp4",
565
- "audio/wav",
566
- "audio/webm",
567
- "audio/ogg",
568
- "audio/flac",
569
- "audio/aac"
570
- ];
571
- const isValidType = validAudioTypes.includes(audioFile.type) || audioFile.type === "" || audioFile.type === "application/octet-stream";
572
- if (!isValidType) {
573
- return new Response(
574
- JSON.stringify({
575
- error: "Invalid file type",
576
- message: `Unsupported audio file type: ${audioFile.type}. Supported types: ${validAudioTypes.join(", ")}, or files with unknown/empty types`
577
- }),
578
- {
579
- status: 400,
580
- headers: { "Content-Type": "application/json" }
581
- }
582
- );
583
- }
584
- const transcription = await runtime.transcriptionService.transcribeFile({
585
- audioFile,
586
- mimeType: audioFile.type,
587
- size: audioFile.size
588
- });
589
- return new Response(
590
- JSON.stringify({
591
- text: transcription,
592
- size: audioFile.size,
593
- type: audioFile.type
594
- }),
595
- {
596
- status: 200,
597
- headers: { "Content-Type": "application/json" }
598
- }
599
- );
600
- } catch (error) {
601
- return new Response(
602
- JSON.stringify({
603
- error: "Transcription failed",
604
- message: error instanceof Error ? error.message : "Unknown error occurred during transcription"
605
- }),
606
- {
607
- status: 500,
608
- headers: { "Content-Type": "application/json" }
609
- }
610
- );
611
- }
612
- }
613
-
614
- // src/endpoint.ts
615
- import { logger as logger2 } from "@copilotkitnext/shared";
616
-
617
- // src/middleware.ts
618
21
  import { logger } from "@copilotkitnext/shared";
619
- async function callBeforeRequestMiddleware({
620
- runtime,
621
- request,
622
- path
623
- }) {
624
- const mw = runtime.beforeRequestMiddleware;
625
- if (!mw) return;
626
- if (typeof mw === "function") {
627
- return mw({ runtime, request, path });
628
- }
629
- logger.warn({ mw }, "Unsupported beforeRequestMiddleware value \u2013 skipped");
630
- return;
631
- }
632
- async function callAfterRequestMiddleware({
633
- runtime,
634
- response,
635
- path
636
- }) {
637
- const mw = runtime.afterRequestMiddleware;
638
- if (!mw) return;
639
- if (typeof mw === "function") {
640
- return mw({ runtime, response, path });
641
- }
642
- logger.warn({ mw }, "Unsupported afterRequestMiddleware value \u2013 skipped");
643
- }
644
-
645
- // src/handlers/handle-connect.ts
646
- import { RunAgentInputSchema as RunAgentInputSchema2 } from "@ag-ui/client";
647
- import { EventEncoder as EventEncoder2 } from "@ag-ui/encoder";
648
- async function handleConnectAgent({
649
- runtime,
650
- request,
651
- agentId
652
- }) {
653
- try {
654
- const agents = await runtime.agents;
655
- if (!agents[agentId]) {
656
- return new Response(
657
- JSON.stringify({
658
- error: "Agent not found",
659
- message: `Agent '${agentId}' does not exist`
660
- }),
661
- {
662
- status: 404,
663
- headers: { "Content-Type": "application/json" }
664
- }
665
- );
666
- }
667
- const stream = new TransformStream();
668
- const writer = stream.writable.getWriter();
669
- const encoder = new EventEncoder2();
670
- let streamClosed = false;
671
- (async () => {
672
- let input;
673
- try {
674
- const requestBody = await request.json();
675
- input = RunAgentInputSchema2.parse(requestBody);
676
- } catch {
677
- return new Response(
678
- JSON.stringify({
679
- error: "Invalid request body"
680
- }),
681
- { status: 400 }
682
- );
683
- }
684
- runtime.runner.connect({
685
- threadId: input.threadId
686
- }).subscribe({
687
- next: async (event) => {
688
- if (!request.signal.aborted && !streamClosed) {
689
- try {
690
- await writer.write(encoder.encode(event));
691
- } catch (error) {
692
- if (error instanceof Error && error.name === "AbortError") {
693
- streamClosed = true;
694
- }
695
- }
696
- }
697
- },
698
- error: async (error) => {
699
- console.error("Error running agent:", error);
700
- if (!streamClosed) {
701
- try {
702
- await writer.close();
703
- streamClosed = true;
704
- } catch {
705
- }
706
- }
707
- },
708
- complete: async () => {
709
- if (!streamClosed) {
710
- try {
711
- await writer.close();
712
- streamClosed = true;
713
- } catch {
714
- }
715
- }
716
- }
717
- });
718
- })().catch((error) => {
719
- console.error("Error running agent:", error);
720
- console.error(
721
- "Error stack:",
722
- error instanceof Error ? error.stack : "No stack trace"
723
- );
724
- console.error("Error details:", {
725
- name: error instanceof Error ? error.name : "Unknown",
726
- message: error instanceof Error ? error.message : String(error),
727
- cause: error instanceof Error ? error.cause : void 0
728
- });
729
- if (!streamClosed) {
730
- try {
731
- writer.close();
732
- streamClosed = true;
733
- } catch {
734
- }
735
- }
736
- });
737
- return new Response(stream.readable, {
738
- status: 200,
739
- headers: {
740
- "Content-Type": "text/event-stream",
741
- "Cache-Control": "no-cache",
742
- Connection: "keep-alive"
743
- }
744
- });
745
- } catch (error) {
746
- console.error("Error running agent:", error);
747
- console.error(
748
- "Error stack:",
749
- error instanceof Error ? error.stack : "No stack trace"
750
- );
751
- console.error("Error details:", {
752
- name: error instanceof Error ? error.name : "Unknown",
753
- message: error instanceof Error ? error.message : String(error),
754
- cause: error instanceof Error ? error.cause : void 0
755
- });
756
- return new Response(
757
- JSON.stringify({
758
- error: "Failed to run agent",
759
- message: error instanceof Error ? error.message : "Unknown error"
760
- }),
761
- {
762
- status: 500,
763
- headers: { "Content-Type": "application/json" }
764
- }
765
- );
766
- }
767
- }
768
-
769
- // src/handlers/handle-stop.ts
770
- import { EventType as EventType2 } from "@ag-ui/client";
771
- async function handleStopAgent({
772
- runtime,
773
- request,
774
- agentId,
775
- threadId
776
- }) {
777
- try {
778
- const agents = await runtime.agents;
779
- if (!agents[agentId]) {
780
- return new Response(
781
- JSON.stringify({
782
- error: "Agent not found",
783
- message: `Agent '${agentId}' does not exist`
784
- }),
785
- {
786
- status: 404,
787
- headers: { "Content-Type": "application/json" }
788
- }
789
- );
790
- }
791
- const stopped = await runtime.runner.stop({ threadId });
792
- if (!stopped) {
793
- return new Response(
794
- JSON.stringify({
795
- stopped: false,
796
- message: `No active run for thread '${threadId}'.`
797
- }),
798
- {
799
- status: 200,
800
- headers: { "Content-Type": "application/json" }
801
- }
802
- );
803
- }
804
- return new Response(
805
- JSON.stringify({
806
- stopped: true,
807
- interrupt: {
808
- type: EventType2.RUN_ERROR,
809
- message: "Run stopped by user",
810
- code: "STOPPED"
811
- }
812
- }),
813
- {
814
- status: 200,
815
- headers: { "Content-Type": "application/json" }
816
- }
817
- );
818
- } catch (error) {
819
- console.error("Error stopping agent run:", error);
820
- return new Response(
821
- JSON.stringify({
822
- error: "Failed to stop agent",
823
- message: error instanceof Error ? error.message : "Unknown error"
824
- }),
825
- {
826
- status: 500,
827
- headers: { "Content-Type": "application/json" }
828
- }
829
- );
830
- }
831
- }
832
-
833
- // src/endpoint.ts
834
22
  function createCopilotEndpoint({ runtime, basePath }) {
835
23
  const app = new Hono();
836
24
  return app.basePath(basePath).use(
@@ -853,7 +41,7 @@ function createCopilotEndpoint({ runtime, basePath }) {
853
41
  c.set("modifiedRequest", maybeModifiedRequest);
854
42
  }
855
43
  } catch (error) {
856
- logger2.error({ err: error, url: request.url, path }, "Error running before request middleware");
44
+ logger.error({ err: error, url: request.url, path }, "Error running before request middleware");
857
45
  if (error instanceof Response) {
858
46
  return error;
859
47
  }
@@ -869,7 +57,7 @@ function createCopilotEndpoint({ runtime, basePath }) {
869
57
  response,
870
58
  path
871
59
  }).catch((error) => {
872
- logger2.error({ err: error, url: c.req.url, path }, "Error running after request middleware");
60
+ logger.error({ err: error, url: c.req.url, path }, "Error running after request middleware");
873
61
  });
874
62
  }).post("/agent/:agentId/run", async (c) => {
875
63
  const agentId = c.req.param("agentId");
@@ -881,7 +69,7 @@ function createCopilotEndpoint({ runtime, basePath }) {
881
69
  agentId
882
70
  });
883
71
  } catch (error) {
884
- logger2.error({ err: error, url: request.url, path: c.req.path }, "Error running request handler");
72
+ logger.error({ err: error, url: request.url, path: c.req.path }, "Error running request handler");
885
73
  throw error;
886
74
  }
887
75
  }).post("/agent/:agentId/connect", async (c) => {
@@ -894,7 +82,7 @@ function createCopilotEndpoint({ runtime, basePath }) {
894
82
  agentId
895
83
  });
896
84
  } catch (error) {
897
- logger2.error({ err: error, url: request.url, path: c.req.path }, "Error running request handler");
85
+ logger.error({ err: error, url: request.url, path: c.req.path }, "Error running request handler");
898
86
  throw error;
899
87
  }
900
88
  }).post("/agent/:agentId/stop/:threadId", async (c) => {
@@ -909,7 +97,7 @@ function createCopilotEndpoint({ runtime, basePath }) {
909
97
  threadId
910
98
  });
911
99
  } catch (error) {
912
- logger2.error({ err: error, url: request.url, path: c.req.path }, "Error running request handler");
100
+ logger.error({ err: error, url: request.url, path: c.req.path }, "Error running request handler");
913
101
  throw error;
914
102
  }
915
103
  }).get("/info", async (c) => {
@@ -920,7 +108,7 @@ function createCopilotEndpoint({ runtime, basePath }) {
920
108
  request
921
109
  });
922
110
  } catch (error) {
923
- logger2.error({ err: error, url: request.url, path: c.req.path }, "Error running request handler");
111
+ logger.error({ err: error, url: request.url, path: c.req.path }, "Error running request handler");
924
112
  throw error;
925
113
  }
926
114
  }).post("/transcribe", async (c) => {
@@ -931,22 +119,139 @@ function createCopilotEndpoint({ runtime, basePath }) {
931
119
  request
932
120
  });
933
121
  } catch (error) {
934
- logger2.error({ err: error, url: request.url, path: c.req.path }, "Error running request handler");
122
+ logger.error({ err: error, url: request.url, path: c.req.path }, "Error running request handler");
123
+ throw error;
124
+ }
125
+ }).notFound((c) => {
126
+ return c.json({ error: "Not found" }, 404);
127
+ });
128
+ }
129
+
130
+ // src/endpoints/hono-single.ts
131
+ import { Hono as Hono2 } from "hono";
132
+ import { cors as cors2 } from "hono/cors";
133
+ import { logger as logger2 } from "@copilotkitnext/shared";
134
+ function createCopilotEndpointSingleRoute({ runtime, basePath }) {
135
+ const app = new Hono2();
136
+ const routePath = normalizePath(basePath);
137
+ return app.basePath(routePath).use(
138
+ "*",
139
+ cors2({
140
+ origin: "*",
141
+ allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"],
142
+ allowHeaders: ["*"]
143
+ })
144
+ ).use("*", async (c, next) => {
145
+ const request = c.req.raw;
146
+ const path = c.req.path;
147
+ try {
148
+ const maybeModifiedRequest = await callBeforeRequestMiddleware({
149
+ runtime,
150
+ request,
151
+ path
152
+ });
153
+ if (maybeModifiedRequest) {
154
+ c.set("modifiedRequest", maybeModifiedRequest);
155
+ }
156
+ } catch (error) {
157
+ logger2.error({ err: error, url: request.url, path }, "Error running before request middleware");
158
+ if (error instanceof Response) {
159
+ return error;
160
+ }
161
+ throw error;
162
+ }
163
+ await next();
164
+ }).use("*", async (c, next) => {
165
+ await next();
166
+ const response = c.res;
167
+ const path = c.req.path;
168
+ callAfterRequestMiddleware({
169
+ runtime,
170
+ response,
171
+ path
172
+ }).catch((error) => {
173
+ logger2.error({ err: error, url: c.req.url, path }, "Error running after request middleware");
174
+ });
175
+ }).post("/", async (c) => {
176
+ const request = c.get("modifiedRequest") || c.req.raw;
177
+ let methodCall;
178
+ try {
179
+ methodCall = await parseMethodCall(request);
180
+ } catch (error) {
181
+ if (error instanceof Response) {
182
+ logger2.warn({ url: request.url }, "Invalid single-route payload");
183
+ return error;
184
+ }
185
+ logger2.warn({ err: error, url: request.url }, "Invalid single-route payload");
186
+ return c.json(
187
+ {
188
+ error: "invalid_request",
189
+ message: error instanceof Error ? error.message : "Invalid request payload"
190
+ },
191
+ 400
192
+ );
193
+ }
194
+ try {
195
+ switch (methodCall.method) {
196
+ case "agent/run": {
197
+ const agentId = expectString(methodCall.params, "agentId");
198
+ const handlerRequest = createJsonRequest(request, methodCall.body);
199
+ return await handleRunAgent({ runtime, request: handlerRequest, agentId });
200
+ }
201
+ case "agent/connect": {
202
+ const agentId = expectString(methodCall.params, "agentId");
203
+ const handlerRequest = createJsonRequest(request, methodCall.body);
204
+ return await handleConnectAgent({ runtime, request: handlerRequest, agentId });
205
+ }
206
+ case "agent/stop": {
207
+ const agentId = expectString(methodCall.params, "agentId");
208
+ const threadId = expectString(methodCall.params, "threadId");
209
+ return await handleStopAgent({ runtime, request, agentId, threadId });
210
+ }
211
+ case "info": {
212
+ return await handleGetRuntimeInfo({ runtime, request });
213
+ }
214
+ case "transcribe": {
215
+ return await handleTranscribe({ runtime, request });
216
+ }
217
+ default: {
218
+ const exhaustiveCheck = methodCall.method;
219
+ return exhaustiveCheck;
220
+ }
221
+ }
222
+ } catch (error) {
223
+ if (error instanceof Response) {
224
+ return error;
225
+ }
226
+ logger2.error({ err: error, url: request.url, method: methodCall.method }, "Error running single-route handler");
935
227
  throw error;
936
228
  }
937
229
  }).notFound((c) => {
938
230
  return c.json({ error: "Not found" }, 404);
939
231
  });
940
232
  }
233
+ function normalizePath(path) {
234
+ if (!path) {
235
+ throw new Error("basePath must be provided for single-route endpoint");
236
+ }
237
+ if (!path.startsWith("/")) {
238
+ return `/${path}`;
239
+ }
240
+ if (path.length > 1 && path.endsWith("/")) {
241
+ return path.slice(0, -1);
242
+ }
243
+ return path;
244
+ }
941
245
 
942
246
  // src/runner/index.ts
943
- import { finalizeRunEvents as finalizeRunEvents2 } from "@copilotkitnext/shared";
247
+ import { finalizeRunEvents } from "@copilotkitnext/shared";
944
248
  export {
945
249
  AgentRunner,
946
250
  CopilotRuntime,
947
251
  InMemoryAgentRunner,
948
252
  VERSION,
949
253
  createCopilotEndpoint,
950
- finalizeRunEvents2 as finalizeRunEvents
254
+ createCopilotEndpointSingleRoute,
255
+ finalizeRunEvents
951
256
  };
952
257
  //# sourceMappingURL=index.mjs.map