@copilotkitnext/runtime 0.0.1 → 0.0.2
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/.turbo/turbo-build.log +23 -22
- package/dist/index.js +14 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +14 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/runner/in-memory.ts +39 -20
- package/README-RUNNERS.md +0 -78
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@copilotkitnext/runtime",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Server-side runtime package for CopilotKit2",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"ioredis": "^5.7.0",
|
|
36
36
|
"kysely": "^0.28.5",
|
|
37
37
|
"rxjs": "7.8.1",
|
|
38
|
-
"@copilotkitnext/shared": "0.0.
|
|
38
|
+
"@copilotkitnext/shared": "0.0.2"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"better-sqlite3": "^12.2.0",
|
package/src/runner/in-memory.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
type AgentRunnerStopRequest,
|
|
7
7
|
} from "./agent-runner";
|
|
8
8
|
import { Observable, ReplaySubject } from "rxjs";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
10
|
BaseEvent,
|
|
11
11
|
Message,
|
|
12
12
|
EventType,
|
|
@@ -16,7 +16,8 @@ import {
|
|
|
16
16
|
ToolCallStartEvent,
|
|
17
17
|
ToolCallArgsEvent,
|
|
18
18
|
ToolCallEndEvent,
|
|
19
|
-
ToolCallResultEvent
|
|
19
|
+
ToolCallResultEvent,
|
|
20
|
+
MessagesSnapshotEvent,
|
|
20
21
|
} from "@ag-ui/client";
|
|
21
22
|
import { compactEvents } from "./event-compaction";
|
|
22
23
|
|
|
@@ -42,7 +43,7 @@ class InMemoryEventStore {
|
|
|
42
43
|
|
|
43
44
|
/** Current run ID */
|
|
44
45
|
currentRunId: string | null = null;
|
|
45
|
-
|
|
46
|
+
|
|
46
47
|
/** Historic completed runs */
|
|
47
48
|
historicRuns: HistoricRun[] = [];
|
|
48
49
|
}
|
|
@@ -137,12 +138,12 @@ export class InMemoryAgentRunner extends AgentRunner {
|
|
|
137
138
|
// Track seen message IDs and current run events for this run
|
|
138
139
|
const seenMessageIds = new Set<string>();
|
|
139
140
|
const currentRunEvents: BaseEvent[] = [];
|
|
140
|
-
|
|
141
|
+
|
|
141
142
|
// Get all previously seen message IDs from historic runs
|
|
142
143
|
const historicMessageIds = new Set<string>();
|
|
143
144
|
for (const run of store.historicRuns) {
|
|
144
145
|
for (const event of run.events) {
|
|
145
|
-
if (
|
|
146
|
+
if ("messageId" in event && typeof event.messageId === "string") {
|
|
146
147
|
historicMessageIds.add(event.messageId);
|
|
147
148
|
}
|
|
148
149
|
}
|
|
@@ -163,10 +164,23 @@ export class InMemoryAgentRunner extends AgentRunner {
|
|
|
163
164
|
// Get parent run ID for chaining
|
|
164
165
|
const lastRun = store.historicRuns[store.historicRuns.length - 1];
|
|
165
166
|
const parentRunId = lastRun?.runId ?? null;
|
|
166
|
-
|
|
167
|
+
|
|
167
168
|
try {
|
|
168
169
|
await request.agent.runAgent(request.input, {
|
|
169
170
|
onEvent: ({ event }) => {
|
|
171
|
+
if (event.type === EventType.MESSAGES_SNAPSHOT) {
|
|
172
|
+
const messagesSnapshotEvent = event as MessagesSnapshotEvent;
|
|
173
|
+
const fixedMessages = [];
|
|
174
|
+
const messageIds = new Set<string>();
|
|
175
|
+
for (const message of messagesSnapshotEvent.messages) {
|
|
176
|
+
if (messageIds.has(message.id)) {
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
fixedMessages.push(message);
|
|
180
|
+
messageIds.add(message.id);
|
|
181
|
+
}
|
|
182
|
+
messagesSnapshotEvent.messages = fixedMessages;
|
|
183
|
+
}
|
|
170
184
|
runSubject.next(event); // For run() return - only agent events
|
|
171
185
|
nextSubject.next(event); // For connect() / store - all events
|
|
172
186
|
currentRunEvents.push(event); // Accumulate for storage
|
|
@@ -184,14 +198,14 @@ export class InMemoryAgentRunner extends AgentRunner {
|
|
|
184
198
|
if (!seenMessageIds.has(message.id)) {
|
|
185
199
|
seenMessageIds.add(message.id);
|
|
186
200
|
const events = this.convertMessageToEvents(message);
|
|
187
|
-
|
|
201
|
+
|
|
188
202
|
// Check if this message is NEW (not in historic runs)
|
|
189
203
|
const isNewMessage = !historicMessageIds.has(message.id);
|
|
190
|
-
|
|
204
|
+
|
|
191
205
|
for (const event of events) {
|
|
192
206
|
// Always emit to stream for context
|
|
193
207
|
nextSubject.next(event);
|
|
194
|
-
|
|
208
|
+
|
|
195
209
|
// Store if this is a NEW message for this run
|
|
196
210
|
if (isNewMessage) {
|
|
197
211
|
currentRunEvents.push(event);
|
|
@@ -202,11 +216,12 @@ export class InMemoryAgentRunner extends AgentRunner {
|
|
|
202
216
|
}
|
|
203
217
|
},
|
|
204
218
|
});
|
|
205
|
-
|
|
219
|
+
|
|
206
220
|
// Store the completed run in memory with ONLY its events
|
|
207
221
|
if (store.currentRunId) {
|
|
208
222
|
// Compact the events before storing (like SQLite does)
|
|
209
223
|
const compactedEvents = compactEvents(currentRunEvents);
|
|
224
|
+
|
|
210
225
|
store.historicRuns.push({
|
|
211
226
|
threadId: request.threadId,
|
|
212
227
|
runId: store.currentRunId,
|
|
@@ -215,7 +230,7 @@ export class InMemoryAgentRunner extends AgentRunner {
|
|
|
215
230
|
createdAt: Date.now(),
|
|
216
231
|
});
|
|
217
232
|
}
|
|
218
|
-
|
|
233
|
+
|
|
219
234
|
// Complete the run
|
|
220
235
|
store.isRunning = false;
|
|
221
236
|
store.currentRunId = null;
|
|
@@ -234,7 +249,7 @@ export class InMemoryAgentRunner extends AgentRunner {
|
|
|
234
249
|
createdAt: Date.now(),
|
|
235
250
|
});
|
|
236
251
|
}
|
|
237
|
-
|
|
252
|
+
|
|
238
253
|
// Complete the run
|
|
239
254
|
store.isRunning = false;
|
|
240
255
|
store.currentRunId = null;
|
|
@@ -276,37 +291,41 @@ export class InMemoryAgentRunner extends AgentRunner {
|
|
|
276
291
|
for (const run of store.historicRuns) {
|
|
277
292
|
allHistoricEvents.push(...run.events);
|
|
278
293
|
}
|
|
279
|
-
|
|
294
|
+
|
|
280
295
|
// Apply compaction to all historic events together (like SQLite)
|
|
281
296
|
const compactedEvents = compactEvents(allHistoricEvents);
|
|
282
|
-
|
|
297
|
+
|
|
283
298
|
// Emit compacted events and track message IDs
|
|
284
299
|
const emittedMessageIds = new Set<string>();
|
|
285
300
|
for (const event of compactedEvents) {
|
|
286
301
|
connectionSubject.next(event);
|
|
287
|
-
if (
|
|
302
|
+
if ("messageId" in event && typeof event.messageId === "string") {
|
|
288
303
|
emittedMessageIds.add(event.messageId);
|
|
289
304
|
}
|
|
290
305
|
}
|
|
291
|
-
|
|
306
|
+
|
|
292
307
|
// Bridge active run to connection if exists
|
|
293
308
|
if (store.subject && store.isRunning) {
|
|
294
309
|
store.subject.subscribe({
|
|
295
310
|
next: (event) => {
|
|
296
311
|
// Skip message events that we've already emitted from historic
|
|
297
|
-
if (
|
|
312
|
+
if (
|
|
313
|
+
"messageId" in event &&
|
|
314
|
+
typeof event.messageId === "string" &&
|
|
315
|
+
emittedMessageIds.has(event.messageId)
|
|
316
|
+
) {
|
|
298
317
|
return;
|
|
299
318
|
}
|
|
300
319
|
connectionSubject.next(event);
|
|
301
320
|
},
|
|
302
321
|
complete: () => connectionSubject.complete(),
|
|
303
|
-
error: (err) => connectionSubject.error(err)
|
|
322
|
+
error: (err) => connectionSubject.error(err),
|
|
304
323
|
});
|
|
305
324
|
} else {
|
|
306
325
|
// No active run, complete after historic events
|
|
307
326
|
connectionSubject.complete();
|
|
308
327
|
}
|
|
309
|
-
|
|
328
|
+
|
|
310
329
|
return connectionSubject.asObservable();
|
|
311
330
|
}
|
|
312
331
|
|
|
@@ -319,4 +338,4 @@ export class InMemoryAgentRunner extends AgentRunner {
|
|
|
319
338
|
stop(_request: AgentRunnerStopRequest): Promise<boolean | undefined> {
|
|
320
339
|
throw new Error("Method not implemented.");
|
|
321
340
|
}
|
|
322
|
-
}
|
|
341
|
+
}
|
package/README-RUNNERS.md
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
# Agent Runners
|
|
2
|
-
|
|
3
|
-
CopilotKit Runtime provides two agent runners for different use cases:
|
|
4
|
-
|
|
5
|
-
## InMemoryAgentRunner (Default)
|
|
6
|
-
|
|
7
|
-
The default runner that stores all data in memory. Perfect for development and applications that don't need persistence.
|
|
8
|
-
|
|
9
|
-
```typescript
|
|
10
|
-
import { CopilotRuntime, InMemoryAgentRunner } from "@copilotkitnext/runtime";
|
|
11
|
-
|
|
12
|
-
// Default - uses InMemoryAgentRunner automatically
|
|
13
|
-
const runtime = new CopilotRuntime({
|
|
14
|
-
agents: myAgents,
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
// Or explicitly
|
|
18
|
-
const runtime = new CopilotRuntime({
|
|
19
|
-
agents: myAgents,
|
|
20
|
-
runner: new InMemoryAgentRunner(),
|
|
21
|
-
});
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
**Features:**
|
|
25
|
-
|
|
26
|
-
- No external dependencies
|
|
27
|
-
- Fast performance
|
|
28
|
-
- Data is lost when process restarts
|
|
29
|
-
- Perfect for development and stateless applications
|
|
30
|
-
|
|
31
|
-
## SqliteAgentRunner
|
|
32
|
-
|
|
33
|
-
Provides persistent storage using SQLite. Ideal for applications that need to preserve conversation history across restarts.
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
import { CopilotRuntime, SqliteAgentRunner } from "@copilotkitnext/runtime";
|
|
37
|
-
|
|
38
|
-
const runtime = new CopilotRuntime({
|
|
39
|
-
agents: myAgents,
|
|
40
|
-
runner: new SqliteAgentRunner("./data/copilot.db"),
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// Or use in-memory SQLite (data persists during runtime only)
|
|
44
|
-
const runtime = new CopilotRuntime({
|
|
45
|
-
agents: myAgents,
|
|
46
|
-
runner: new SqliteAgentRunner(":memory:"),
|
|
47
|
-
});
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
**Features:**
|
|
51
|
-
|
|
52
|
-
- Persistent storage across restarts
|
|
53
|
-
- Maintains conversation history
|
|
54
|
-
- Parent-child run relationships
|
|
55
|
-
- Event compaction for historic runs
|
|
56
|
-
|
|
57
|
-
**Requirements:**
|
|
58
|
-
|
|
59
|
-
- Requires `better-sqlite3` to be installed:
|
|
60
|
-
```bash
|
|
61
|
-
npm install better-sqlite3
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
## Choosing the Right Runner
|
|
65
|
-
|
|
66
|
-
- **Use InMemoryAgentRunner when:**
|
|
67
|
-
- Building prototypes or demos
|
|
68
|
-
- Running in serverless environments
|
|
69
|
-
- You don't need conversation history
|
|
70
|
-
- You want zero external dependencies
|
|
71
|
-
|
|
72
|
-
- **Use SqliteAgentRunner when:**
|
|
73
|
-
- You need persistent conversation history
|
|
74
|
-
- Building production applications
|
|
75
|
-
- You want to analyze historic conversations
|
|
76
|
-
- Running on a traditional server
|
|
77
|
-
|
|
78
|
-
Both runners implement the same `AgentRunner` interface, so you can switch between them without changing your application code.
|