@copilotkitnext/runtime 0.0.17-alpha.0 → 0.0.18
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.d.mts +20 -6
- package/dist/index.d.ts +20 -6
- package/dist/index.js +160 -156
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +154 -151
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "@copilotkitnext/runtime",
|
|
4
|
-
version: "0.0.
|
|
4
|
+
version: "0.0.18",
|
|
5
5
|
description: "Server-side runtime package for CopilotKit2",
|
|
6
6
|
main: "dist/index.js",
|
|
7
7
|
types: "dist/index.d.ts",
|
|
@@ -63,6 +63,7 @@ import {
|
|
|
63
63
|
EventType,
|
|
64
64
|
compactEvents
|
|
65
65
|
} from "@ag-ui/client";
|
|
66
|
+
import { finalizeRunEvents } from "@copilotkitnext/shared";
|
|
66
67
|
var InMemoryEventStore = class {
|
|
67
68
|
constructor(threadId) {
|
|
68
69
|
this.threadId = threadId;
|
|
@@ -71,12 +72,18 @@ var InMemoryEventStore = class {
|
|
|
71
72
|
subject = null;
|
|
72
73
|
/** True while a run is actively producing events. */
|
|
73
74
|
isRunning = false;
|
|
74
|
-
/** Lets stop() cancel the current producer. */
|
|
75
|
-
abortController = new AbortController();
|
|
76
75
|
/** Current run ID */
|
|
77
76
|
currentRunId = null;
|
|
78
77
|
/** Historic completed runs */
|
|
79
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;
|
|
80
87
|
};
|
|
81
88
|
var GLOBAL_STORE = /* @__PURE__ */ new Map();
|
|
82
89
|
var InMemoryAgentRunner = class extends AgentRunner {
|
|
@@ -92,8 +99,11 @@ var InMemoryAgentRunner = class extends AgentRunner {
|
|
|
92
99
|
}
|
|
93
100
|
store.isRunning = true;
|
|
94
101
|
store.currentRunId = request.input.runId;
|
|
102
|
+
store.agent = request.agent;
|
|
103
|
+
store.stopRequested = false;
|
|
95
104
|
const seenMessageIds = /* @__PURE__ */ new Set();
|
|
96
105
|
const currentRunEvents = [];
|
|
106
|
+
store.currentEvents = currentRunEvents;
|
|
97
107
|
const historicMessageIds = /* @__PURE__ */ new Set();
|
|
98
108
|
for (const run of store.historicRuns) {
|
|
99
109
|
for (const event of run.events) {
|
|
@@ -112,8 +122,8 @@ var InMemoryAgentRunner = class extends AgentRunner {
|
|
|
112
122
|
const nextSubject = new ReplaySubject(Infinity);
|
|
113
123
|
const prevSubject = store.subject;
|
|
114
124
|
store.subject = nextSubject;
|
|
115
|
-
store.abortController = new AbortController();
|
|
116
125
|
const runSubject = new ReplaySubject(Infinity);
|
|
126
|
+
store.runSubject = runSubject;
|
|
117
127
|
const runAgent = async () => {
|
|
118
128
|
const lastRun = store.historicRuns[store.historicRuns.length - 1];
|
|
119
129
|
const parentRunId = lastRun?.runId ?? null;
|
|
@@ -156,6 +166,13 @@ var InMemoryAgentRunner = class extends AgentRunner {
|
|
|
156
166
|
}
|
|
157
167
|
}
|
|
158
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
|
+
}
|
|
159
176
|
if (store.currentRunId) {
|
|
160
177
|
const compactedEvents = compactEvents(currentRunEvents);
|
|
161
178
|
store.historicRuns.push({
|
|
@@ -166,11 +183,22 @@ var InMemoryAgentRunner = class extends AgentRunner {
|
|
|
166
183
|
createdAt: Date.now()
|
|
167
184
|
});
|
|
168
185
|
}
|
|
169
|
-
store.
|
|
186
|
+
store.currentEvents = null;
|
|
170
187
|
store.currentRunId = null;
|
|
188
|
+
store.agent = null;
|
|
189
|
+
store.runSubject = null;
|
|
190
|
+
store.stopRequested = false;
|
|
191
|
+
store.isRunning = false;
|
|
171
192
|
runSubject.complete();
|
|
172
193
|
nextSubject.complete();
|
|
173
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
|
+
}
|
|
174
202
|
if (store.currentRunId && currentRunEvents.length > 0) {
|
|
175
203
|
const compactedEvents = compactEvents(currentRunEvents);
|
|
176
204
|
store.historicRuns.push({
|
|
@@ -181,8 +209,12 @@ var InMemoryAgentRunner = class extends AgentRunner {
|
|
|
181
209
|
createdAt: Date.now()
|
|
182
210
|
});
|
|
183
211
|
}
|
|
184
|
-
store.
|
|
212
|
+
store.currentEvents = null;
|
|
185
213
|
store.currentRunId = null;
|
|
214
|
+
store.agent = null;
|
|
215
|
+
store.runSubject = null;
|
|
216
|
+
store.stopRequested = false;
|
|
217
|
+
store.isRunning = false;
|
|
186
218
|
runSubject.complete();
|
|
187
219
|
nextSubject.complete();
|
|
188
220
|
}
|
|
@@ -217,7 +249,7 @@ var InMemoryAgentRunner = class extends AgentRunner {
|
|
|
217
249
|
emittedMessageIds.add(event.messageId);
|
|
218
250
|
}
|
|
219
251
|
}
|
|
220
|
-
if (store.subject && store.isRunning) {
|
|
252
|
+
if (store.subject && (store.isRunning || store.stopRequested)) {
|
|
221
253
|
store.subject.subscribe({
|
|
222
254
|
next: (event) => {
|
|
223
255
|
if ("messageId" in event && typeof event.messageId === "string" && emittedMessageIds.has(event.messageId)) {
|
|
@@ -237,9 +269,31 @@ var InMemoryAgentRunner = class extends AgentRunner {
|
|
|
237
269
|
const store = GLOBAL_STORE.get(request.threadId);
|
|
238
270
|
return Promise.resolve(store?.isRunning ?? false);
|
|
239
271
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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
|
+
}
|
|
243
297
|
}
|
|
244
298
|
};
|
|
245
299
|
|
|
@@ -562,9 +616,6 @@ import { logger as logger2 } from "@copilotkitnext/shared";
|
|
|
562
616
|
|
|
563
617
|
// src/middleware.ts
|
|
564
618
|
import { logger } from "@copilotkitnext/shared";
|
|
565
|
-
function isMiddlewareURL(value) {
|
|
566
|
-
return typeof value === "string" && /^https?:\/\//.test(value);
|
|
567
|
-
}
|
|
568
619
|
async function callBeforeRequestMiddleware({
|
|
569
620
|
runtime,
|
|
570
621
|
request,
|
|
@@ -575,77 +626,6 @@ async function callBeforeRequestMiddleware({
|
|
|
575
626
|
if (typeof mw === "function") {
|
|
576
627
|
return mw({ runtime, request, path });
|
|
577
628
|
}
|
|
578
|
-
if (isMiddlewareURL(mw)) {
|
|
579
|
-
const clone = request.clone();
|
|
580
|
-
const url = new URL(request.url);
|
|
581
|
-
const headersObj = {};
|
|
582
|
-
clone.headers.forEach((v, k) => {
|
|
583
|
-
headersObj[k] = v;
|
|
584
|
-
});
|
|
585
|
-
let bodyJson = void 0;
|
|
586
|
-
try {
|
|
587
|
-
bodyJson = await clone.json();
|
|
588
|
-
} catch {
|
|
589
|
-
}
|
|
590
|
-
const payload = {
|
|
591
|
-
method: request.method,
|
|
592
|
-
path: url.pathname,
|
|
593
|
-
query: url.search.startsWith("?") ? url.search.slice(1) : url.search,
|
|
594
|
-
headers: headersObj,
|
|
595
|
-
body: bodyJson
|
|
596
|
-
};
|
|
597
|
-
const ac = new AbortController();
|
|
598
|
-
const to = setTimeout(() => ac.abort(), 2e3);
|
|
599
|
-
let res;
|
|
600
|
-
try {
|
|
601
|
-
res = await fetch(mw, {
|
|
602
|
-
method: "POST",
|
|
603
|
-
headers: {
|
|
604
|
-
"content-type": "application/json",
|
|
605
|
-
"X-CopilotKit-Webhook-Stage": "before_request" /* BeforeRequest */
|
|
606
|
-
},
|
|
607
|
-
body: JSON.stringify(payload),
|
|
608
|
-
signal: ac.signal
|
|
609
|
-
});
|
|
610
|
-
} catch {
|
|
611
|
-
clearTimeout(to);
|
|
612
|
-
throw new Response(void 0, { status: 502 });
|
|
613
|
-
}
|
|
614
|
-
clearTimeout(to);
|
|
615
|
-
if (res.status >= 500) {
|
|
616
|
-
throw new Response(void 0, { status: 502 });
|
|
617
|
-
}
|
|
618
|
-
if (res.status >= 400) {
|
|
619
|
-
const errBody = await res.text();
|
|
620
|
-
throw new Response(errBody || null, {
|
|
621
|
-
status: res.status,
|
|
622
|
-
headers: {
|
|
623
|
-
"content-type": res.headers.get("content-type") || "application/json"
|
|
624
|
-
}
|
|
625
|
-
});
|
|
626
|
-
}
|
|
627
|
-
if (res.status === 204) return;
|
|
628
|
-
let json;
|
|
629
|
-
try {
|
|
630
|
-
json = await res.json();
|
|
631
|
-
} catch {
|
|
632
|
-
return;
|
|
633
|
-
}
|
|
634
|
-
if (json && typeof json === "object") {
|
|
635
|
-
const { headers, body } = json;
|
|
636
|
-
const init = {
|
|
637
|
-
method: request.method
|
|
638
|
-
};
|
|
639
|
-
if (headers) {
|
|
640
|
-
init.headers = headers;
|
|
641
|
-
}
|
|
642
|
-
if (body !== void 0 && request.method !== "GET" && request.method !== "HEAD") {
|
|
643
|
-
init.body = JSON.stringify(body);
|
|
644
|
-
}
|
|
645
|
-
return new Request(request.url, init);
|
|
646
|
-
}
|
|
647
|
-
return;
|
|
648
|
-
}
|
|
649
629
|
logger.warn({ mw }, "Unsupported beforeRequestMiddleware value \u2013 skipped");
|
|
650
630
|
return;
|
|
651
631
|
}
|
|
@@ -659,45 +639,6 @@ async function callAfterRequestMiddleware({
|
|
|
659
639
|
if (typeof mw === "function") {
|
|
660
640
|
return mw({ runtime, response, path });
|
|
661
641
|
}
|
|
662
|
-
if (isMiddlewareURL(mw)) {
|
|
663
|
-
const clone = response.clone();
|
|
664
|
-
const headersObj = {};
|
|
665
|
-
clone.headers.forEach((v, k) => {
|
|
666
|
-
headersObj[k] = v;
|
|
667
|
-
});
|
|
668
|
-
let body = "";
|
|
669
|
-
try {
|
|
670
|
-
body = await clone.text();
|
|
671
|
-
} catch {
|
|
672
|
-
}
|
|
673
|
-
const payload = {
|
|
674
|
-
status: clone.status,
|
|
675
|
-
headers: headersObj,
|
|
676
|
-
body
|
|
677
|
-
};
|
|
678
|
-
const ac = new AbortController();
|
|
679
|
-
const to = setTimeout(() => ac.abort(), 2e3);
|
|
680
|
-
let res;
|
|
681
|
-
try {
|
|
682
|
-
res = await fetch(mw, {
|
|
683
|
-
method: "POST",
|
|
684
|
-
headers: {
|
|
685
|
-
"content-type": "application/json",
|
|
686
|
-
"X-CopilotKit-Webhook-Stage": "after_request" /* AfterRequest */
|
|
687
|
-
},
|
|
688
|
-
body: JSON.stringify(payload),
|
|
689
|
-
signal: ac.signal
|
|
690
|
-
});
|
|
691
|
-
} finally {
|
|
692
|
-
clearTimeout(to);
|
|
693
|
-
}
|
|
694
|
-
if (!res.ok) {
|
|
695
|
-
throw new Error(
|
|
696
|
-
`after_request webhook ${mw} responded with ${res.status}`
|
|
697
|
-
);
|
|
698
|
-
}
|
|
699
|
-
return;
|
|
700
|
-
}
|
|
701
642
|
logger.warn({ mw }, "Unsupported afterRequestMiddleware value \u2013 skipped");
|
|
702
643
|
}
|
|
703
644
|
|
|
@@ -825,11 +766,72 @@ async function handleConnectAgent({
|
|
|
825
766
|
}
|
|
826
767
|
}
|
|
827
768
|
|
|
828
|
-
// src/
|
|
829
|
-
|
|
769
|
+
// src/handlers/handle-stop.ts
|
|
770
|
+
import { EventType as EventType2 } from "@ag-ui/client";
|
|
771
|
+
async function handleStopAgent({
|
|
830
772
|
runtime,
|
|
831
|
-
|
|
773
|
+
request,
|
|
774
|
+
agentId,
|
|
775
|
+
threadId
|
|
832
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
|
+
function createCopilotEndpoint({ runtime, basePath }) {
|
|
833
835
|
const app = new Hono();
|
|
834
836
|
return app.basePath(basePath).use(
|
|
835
837
|
"*",
|
|
@@ -851,10 +853,7 @@ function createCopilotEndpoint({
|
|
|
851
853
|
c.set("modifiedRequest", maybeModifiedRequest);
|
|
852
854
|
}
|
|
853
855
|
} catch (error) {
|
|
854
|
-
logger2.error(
|
|
855
|
-
{ err: error, url: request.url, path },
|
|
856
|
-
"Error running before request middleware"
|
|
857
|
-
);
|
|
856
|
+
logger2.error({ err: error, url: request.url, path }, "Error running before request middleware");
|
|
858
857
|
if (error instanceof Response) {
|
|
859
858
|
return error;
|
|
860
859
|
}
|
|
@@ -870,10 +869,7 @@ function createCopilotEndpoint({
|
|
|
870
869
|
response,
|
|
871
870
|
path
|
|
872
871
|
}).catch((error) => {
|
|
873
|
-
logger2.error(
|
|
874
|
-
{ err: error, url: c.req.url, path },
|
|
875
|
-
"Error running after request middleware"
|
|
876
|
-
);
|
|
872
|
+
logger2.error({ err: error, url: c.req.url, path }, "Error running after request middleware");
|
|
877
873
|
});
|
|
878
874
|
}).post("/agent/:agentId/run", async (c) => {
|
|
879
875
|
const agentId = c.req.param("agentId");
|
|
@@ -885,10 +881,7 @@ function createCopilotEndpoint({
|
|
|
885
881
|
agentId
|
|
886
882
|
});
|
|
887
883
|
} catch (error) {
|
|
888
|
-
logger2.error(
|
|
889
|
-
{ err: error, url: request.url, path: c.req.path },
|
|
890
|
-
"Error running request handler"
|
|
891
|
-
);
|
|
884
|
+
logger2.error({ err: error, url: request.url, path: c.req.path }, "Error running request handler");
|
|
892
885
|
throw error;
|
|
893
886
|
}
|
|
894
887
|
}).post("/agent/:agentId/connect", async (c) => {
|
|
@@ -901,10 +894,22 @@ function createCopilotEndpoint({
|
|
|
901
894
|
agentId
|
|
902
895
|
});
|
|
903
896
|
} catch (error) {
|
|
904
|
-
logger2.error(
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
897
|
+
logger2.error({ err: error, url: request.url, path: c.req.path }, "Error running request handler");
|
|
898
|
+
throw error;
|
|
899
|
+
}
|
|
900
|
+
}).post("/agent/:agentId/stop/:threadId", async (c) => {
|
|
901
|
+
const agentId = c.req.param("agentId");
|
|
902
|
+
const threadId = c.req.param("threadId");
|
|
903
|
+
const request = c.get("modifiedRequest") || c.req.raw;
|
|
904
|
+
try {
|
|
905
|
+
return await handleStopAgent({
|
|
906
|
+
runtime,
|
|
907
|
+
request,
|
|
908
|
+
agentId,
|
|
909
|
+
threadId
|
|
910
|
+
});
|
|
911
|
+
} catch (error) {
|
|
912
|
+
logger2.error({ err: error, url: request.url, path: c.req.path }, "Error running request handler");
|
|
908
913
|
throw error;
|
|
909
914
|
}
|
|
910
915
|
}).get("/info", async (c) => {
|
|
@@ -915,10 +920,7 @@ function createCopilotEndpoint({
|
|
|
915
920
|
request
|
|
916
921
|
});
|
|
917
922
|
} catch (error) {
|
|
918
|
-
logger2.error(
|
|
919
|
-
{ err: error, url: request.url, path: c.req.path },
|
|
920
|
-
"Error running request handler"
|
|
921
|
-
);
|
|
923
|
+
logger2.error({ err: error, url: request.url, path: c.req.path }, "Error running request handler");
|
|
922
924
|
throw error;
|
|
923
925
|
}
|
|
924
926
|
}).post("/transcribe", async (c) => {
|
|
@@ -929,21 +931,22 @@ function createCopilotEndpoint({
|
|
|
929
931
|
request
|
|
930
932
|
});
|
|
931
933
|
} catch (error) {
|
|
932
|
-
logger2.error(
|
|
933
|
-
{ err: error, url: request.url, path: c.req.path },
|
|
934
|
-
"Error running request handler"
|
|
935
|
-
);
|
|
934
|
+
logger2.error({ err: error, url: request.url, path: c.req.path }, "Error running request handler");
|
|
936
935
|
throw error;
|
|
937
936
|
}
|
|
938
937
|
}).notFound((c) => {
|
|
939
938
|
return c.json({ error: "Not found" }, 404);
|
|
940
939
|
});
|
|
941
940
|
}
|
|
941
|
+
|
|
942
|
+
// src/runner/index.ts
|
|
943
|
+
import { finalizeRunEvents as finalizeRunEvents2 } from "@copilotkitnext/shared";
|
|
942
944
|
export {
|
|
943
945
|
AgentRunner,
|
|
944
946
|
CopilotRuntime,
|
|
945
947
|
InMemoryAgentRunner,
|
|
946
948
|
VERSION,
|
|
947
|
-
createCopilotEndpoint
|
|
949
|
+
createCopilotEndpoint,
|
|
950
|
+
finalizeRunEvents2 as finalizeRunEvents
|
|
948
951
|
};
|
|
949
952
|
//# sourceMappingURL=index.mjs.map
|