@copilotkitnext/runtime 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.
Files changed (47) hide show
  1. package/.cursor/rules/runtime.always.mdc +9 -0
  2. package/.turbo/turbo-build.log +22 -0
  3. package/.turbo/turbo-check-types.log +4 -0
  4. package/.turbo/turbo-lint.log +56 -0
  5. package/.turbo/turbo-test$colon$coverage.log +149 -0
  6. package/.turbo/turbo-test.log +107 -0
  7. package/LICENSE +11 -0
  8. package/README-RUNNERS.md +78 -0
  9. package/dist/index.d.mts +245 -0
  10. package/dist/index.d.ts +245 -0
  11. package/dist/index.js +1873 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/index.mjs +1841 -0
  14. package/dist/index.mjs.map +1 -0
  15. package/eslint.config.mjs +3 -0
  16. package/package.json +62 -0
  17. package/src/__tests__/get-runtime-info.test.ts +117 -0
  18. package/src/__tests__/handle-run.test.ts +69 -0
  19. package/src/__tests__/handle-transcribe.test.ts +289 -0
  20. package/src/__tests__/in-process-agent-runner-messages.test.ts +599 -0
  21. package/src/__tests__/in-process-agent-runner.test.ts +726 -0
  22. package/src/__tests__/middleware.test.ts +432 -0
  23. package/src/__tests__/routing.test.ts +257 -0
  24. package/src/endpoint.ts +150 -0
  25. package/src/handler.ts +3 -0
  26. package/src/handlers/get-runtime-info.ts +50 -0
  27. package/src/handlers/handle-connect.ts +144 -0
  28. package/src/handlers/handle-run.ts +156 -0
  29. package/src/handlers/handle-transcribe.ts +126 -0
  30. package/src/index.ts +8 -0
  31. package/src/middleware.ts +232 -0
  32. package/src/runner/__tests__/enterprise-runner.test.ts +992 -0
  33. package/src/runner/__tests__/event-compaction.test.ts +253 -0
  34. package/src/runner/__tests__/in-memory-runner.test.ts +483 -0
  35. package/src/runner/__tests__/sqlite-runner.test.ts +975 -0
  36. package/src/runner/agent-runner.ts +27 -0
  37. package/src/runner/enterprise.ts +653 -0
  38. package/src/runner/event-compaction.ts +250 -0
  39. package/src/runner/in-memory.ts +322 -0
  40. package/src/runner/index.ts +0 -0
  41. package/src/runner/sqlite.ts +481 -0
  42. package/src/runtime.ts +53 -0
  43. package/src/transcription-service/transcription-service-openai.ts +29 -0
  44. package/src/transcription-service/transcription-service.ts +11 -0
  45. package/tsconfig.json +13 -0
  46. package/tsup.config.ts +11 -0
  47. package/vitest.config.mjs +15 -0
@@ -0,0 +1,245 @@
1
+ import { MaybePromise, NonEmptyRecord } from '@copilotkitnext/shared';
2
+ import { AbstractAgent, RunAgentInput, BaseEvent } from '@ag-ui/client';
3
+ import { Observable } from 'rxjs';
4
+ import * as hono_hono_base from 'hono/hono-base';
5
+ import * as hono_utils_http_status from 'hono/utils/http-status';
6
+ import { Kysely, Generated } from 'kysely';
7
+ import { Redis } from 'ioredis';
8
+
9
+ /**
10
+ * Middleware support for CopilotKit Runtime.
11
+ *
12
+ * A middleware hook can be provided as either:
13
+ * 1. A **callback function** executed in-process.
14
+ * 2. A **webhook URL** (http/https). The runtime will `POST` a JSON payload
15
+ * to the URL and, for *before* hooks, accept an optional modified
16
+ * `Request` object in the response body.
17
+ *
18
+ * Two lifecycle hooks are available:
19
+ * • `BEFORE_REQUEST` – runs *before* the request handler.
20
+ * • `AFTER_REQUEST` – runs *after* the handler returns a `Response`.
21
+ */
22
+
23
+ /** A string beginning with http:// or https:// that points to a webhook endpoint. */
24
+ type MiddlewareURL = `${"http" | "https"}://${string}`;
25
+ interface BeforeRequestMiddlewareParameters {
26
+ runtime: CopilotRuntime;
27
+ request: Request;
28
+ path: string;
29
+ }
30
+ interface AfterRequestMiddlewareParameters {
31
+ runtime: CopilotRuntime;
32
+ response: Response;
33
+ path: string;
34
+ }
35
+ type BeforeRequestMiddlewareFn = (params: BeforeRequestMiddlewareParameters) => MaybePromise<Request | void>;
36
+ type AfterRequestMiddlewareFn = (params: AfterRequestMiddlewareParameters) => MaybePromise<void>;
37
+ /**
38
+ * A middleware value can be either a callback function or a webhook URL.
39
+ */
40
+ type BeforeRequestMiddleware = BeforeRequestMiddlewareFn | MiddlewareURL;
41
+ type AfterRequestMiddleware = AfterRequestMiddlewareFn | MiddlewareURL;
42
+
43
+ interface TranscribeFileOptions {
44
+ audioFile: File;
45
+ /** MIME type of the audio file */
46
+ mimeType?: string;
47
+ /** Size of the audio file in bytes */
48
+ size?: number;
49
+ }
50
+ declare abstract class TranscriptionService {
51
+ abstract transcribeFile(options: TranscribeFileOptions): Promise<string>;
52
+ }
53
+
54
+ interface AgentRunnerRunRequest {
55
+ threadId: string;
56
+ agent: AbstractAgent;
57
+ input: RunAgentInput;
58
+ }
59
+ interface AgentRunnerConnectRequest {
60
+ threadId: string;
61
+ }
62
+ interface AgentRunnerIsRunningRequest {
63
+ threadId: string;
64
+ }
65
+ interface AgentRunnerStopRequest {
66
+ threadId: string;
67
+ }
68
+ declare abstract class AgentRunner {
69
+ abstract run(request: AgentRunnerRunRequest): Observable<BaseEvent>;
70
+ abstract connect(request: AgentRunnerConnectRequest): Observable<BaseEvent>;
71
+ abstract isRunning(request: AgentRunnerIsRunningRequest): Promise<boolean>;
72
+ abstract stop(request: AgentRunnerStopRequest): Promise<boolean | undefined>;
73
+ }
74
+
75
+ declare const VERSION: string;
76
+ /**
77
+ * Options used to construct a `CopilotRuntime` instance.
78
+ */
79
+ interface CopilotRuntimeOptions {
80
+ /** Map of available agents (loaded lazily is fine). */
81
+ agents: MaybePromise<NonEmptyRecord<Record<string, AbstractAgent>>>;
82
+ /** The runner to use for running agents. */
83
+ runner?: AgentRunner;
84
+ /** Optional transcription service for audio processing. */
85
+ transcriptionService?: TranscriptionService;
86
+ /** Optional *before* middleware – callback function or webhook URL. */
87
+ beforeRequestMiddleware?: BeforeRequestMiddleware;
88
+ /** Optional *after* middleware – callback function or webhook URL. */
89
+ afterRequestMiddleware?: AfterRequestMiddleware;
90
+ }
91
+ /**
92
+ * Central runtime object passed to all request handlers.
93
+ */
94
+ declare class CopilotRuntime {
95
+ agents: CopilotRuntimeOptions["agents"];
96
+ transcriptionService: CopilotRuntimeOptions["transcriptionService"];
97
+ beforeRequestMiddleware: CopilotRuntimeOptions["beforeRequestMiddleware"];
98
+ afterRequestMiddleware: CopilotRuntimeOptions["afterRequestMiddleware"];
99
+ runner: AgentRunner;
100
+ constructor({ agents, transcriptionService, beforeRequestMiddleware, afterRequestMiddleware, runner, }: CopilotRuntimeOptions);
101
+ }
102
+
103
+ interface CopilotEndpointParams {
104
+ runtime: CopilotRuntime;
105
+ basePath: string;
106
+ }
107
+ type CopilotEndpointContext = {
108
+ Variables: {
109
+ modifiedRequest?: Request;
110
+ };
111
+ };
112
+ declare function createCopilotEndpoint({ runtime, basePath, }: CopilotEndpointParams): hono_hono_base.HonoBase<CopilotEndpointContext, {
113
+ [x: `${string}/*`]: {};
114
+ } & {
115
+ [x: `${string}/agent/:agentId/run`]: {
116
+ $post: {
117
+ input: {
118
+ param: {
119
+ agentId: string;
120
+ };
121
+ };
122
+ output: {};
123
+ outputFormat: string;
124
+ status: hono_utils_http_status.StatusCode;
125
+ };
126
+ };
127
+ } & {
128
+ [x: `${string}/agent/:agentId/connect`]: {
129
+ $post: {
130
+ input: {
131
+ param: {
132
+ agentId: string;
133
+ };
134
+ };
135
+ output: {};
136
+ outputFormat: string;
137
+ status: hono_utils_http_status.StatusCode;
138
+ };
139
+ };
140
+ } & {
141
+ [x: `${string}/info`]: {
142
+ $get: {
143
+ input: {};
144
+ output: {};
145
+ outputFormat: string;
146
+ status: hono_utils_http_status.StatusCode;
147
+ };
148
+ };
149
+ } & {
150
+ [x: `${string}/transcribe`]: {
151
+ $post: {
152
+ input: {};
153
+ output: {};
154
+ outputFormat: string;
155
+ status: hono_utils_http_status.StatusCode;
156
+ };
157
+ };
158
+ }, string>;
159
+
160
+ declare class InMemoryAgentRunner extends AgentRunner {
161
+ private convertMessageToEvents;
162
+ run(request: AgentRunnerRunRequest): Observable<BaseEvent>;
163
+ connect(request: AgentRunnerConnectRequest): Observable<BaseEvent>;
164
+ isRunning(request: AgentRunnerIsRunningRequest): Promise<boolean>;
165
+ stop(_request: AgentRunnerStopRequest): Promise<boolean | undefined>;
166
+ }
167
+
168
+ interface SqliteAgentRunnerOptions {
169
+ dbPath?: string;
170
+ }
171
+ declare class SqliteAgentRunner extends AgentRunner {
172
+ private db;
173
+ constructor(options?: SqliteAgentRunnerOptions);
174
+ private convertMessageToEvents;
175
+ private initializeSchema;
176
+ private storeRun;
177
+ private getHistoricRuns;
178
+ private getLatestRunId;
179
+ private setRunState;
180
+ private getRunState;
181
+ run(request: AgentRunnerRunRequest): Observable<BaseEvent>;
182
+ connect(request: AgentRunnerConnectRequest): Observable<BaseEvent>;
183
+ isRunning(request: AgentRunnerIsRunningRequest): Promise<boolean>;
184
+ stop(_request: AgentRunnerStopRequest): Promise<boolean | undefined>;
185
+ /**
186
+ * Close the database connection (for cleanup)
187
+ */
188
+ close(): void;
189
+ }
190
+
191
+ interface AgentDatabase {
192
+ agent_runs: {
193
+ id: Generated<number>;
194
+ thread_id: string;
195
+ run_id: string;
196
+ parent_run_id: string | null;
197
+ events: string;
198
+ input: string;
199
+ created_at: number;
200
+ version: number;
201
+ };
202
+ run_state: {
203
+ thread_id: string;
204
+ is_running: number;
205
+ current_run_id: string | null;
206
+ server_id: string | null;
207
+ updated_at: number;
208
+ };
209
+ schema_version: {
210
+ version: number;
211
+ applied_at: number;
212
+ };
213
+ }
214
+ interface EnterpriseAgentRunnerOptions {
215
+ kysely: Kysely<AgentDatabase>;
216
+ redis: Redis;
217
+ redisSub?: Redis;
218
+ streamRetentionMs?: number;
219
+ streamActiveTTLMs?: number;
220
+ lockTTLMs?: number;
221
+ serverId?: string;
222
+ }
223
+ declare class EnterpriseAgentRunner extends AgentRunner {
224
+ private db;
225
+ redis: Redis;
226
+ redisSub: Redis;
227
+ private serverId;
228
+ private streamRetentionMs;
229
+ private streamActiveTTLMs;
230
+ private lockTTLMs;
231
+ constructor(options: EnterpriseAgentRunnerOptions);
232
+ run(request: AgentRunnerRunRequest): Observable<BaseEvent>;
233
+ connect(request: AgentRunnerConnectRequest): Observable<BaseEvent>;
234
+ isRunning(request: AgentRunnerIsRunningRequest): Promise<boolean>;
235
+ stop(request: AgentRunnerStopRequest): Promise<boolean>;
236
+ private convertMessageToEvents;
237
+ private initializeSchema;
238
+ private storeRun;
239
+ private getHistoricRuns;
240
+ private setRunState;
241
+ close(): Promise<void>;
242
+ private generateServerId;
243
+ }
244
+
245
+ export { CopilotRuntime, type CopilotRuntimeOptions, EnterpriseAgentRunner, type EnterpriseAgentRunnerOptions, InMemoryAgentRunner, SqliteAgentRunner, VERSION, createCopilotEndpoint };
@@ -0,0 +1,245 @@
1
+ import { MaybePromise, NonEmptyRecord } from '@copilotkitnext/shared';
2
+ import { AbstractAgent, RunAgentInput, BaseEvent } from '@ag-ui/client';
3
+ import { Observable } from 'rxjs';
4
+ import * as hono_hono_base from 'hono/hono-base';
5
+ import * as hono_utils_http_status from 'hono/utils/http-status';
6
+ import { Kysely, Generated } from 'kysely';
7
+ import { Redis } from 'ioredis';
8
+
9
+ /**
10
+ * Middleware support for CopilotKit Runtime.
11
+ *
12
+ * A middleware hook can be provided as either:
13
+ * 1. A **callback function** executed in-process.
14
+ * 2. A **webhook URL** (http/https). The runtime will `POST` a JSON payload
15
+ * to the URL and, for *before* hooks, accept an optional modified
16
+ * `Request` object in the response body.
17
+ *
18
+ * Two lifecycle hooks are available:
19
+ * • `BEFORE_REQUEST` – runs *before* the request handler.
20
+ * • `AFTER_REQUEST` – runs *after* the handler returns a `Response`.
21
+ */
22
+
23
+ /** A string beginning with http:// or https:// that points to a webhook endpoint. */
24
+ type MiddlewareURL = `${"http" | "https"}://${string}`;
25
+ interface BeforeRequestMiddlewareParameters {
26
+ runtime: CopilotRuntime;
27
+ request: Request;
28
+ path: string;
29
+ }
30
+ interface AfterRequestMiddlewareParameters {
31
+ runtime: CopilotRuntime;
32
+ response: Response;
33
+ path: string;
34
+ }
35
+ type BeforeRequestMiddlewareFn = (params: BeforeRequestMiddlewareParameters) => MaybePromise<Request | void>;
36
+ type AfterRequestMiddlewareFn = (params: AfterRequestMiddlewareParameters) => MaybePromise<void>;
37
+ /**
38
+ * A middleware value can be either a callback function or a webhook URL.
39
+ */
40
+ type BeforeRequestMiddleware = BeforeRequestMiddlewareFn | MiddlewareURL;
41
+ type AfterRequestMiddleware = AfterRequestMiddlewareFn | MiddlewareURL;
42
+
43
+ interface TranscribeFileOptions {
44
+ audioFile: File;
45
+ /** MIME type of the audio file */
46
+ mimeType?: string;
47
+ /** Size of the audio file in bytes */
48
+ size?: number;
49
+ }
50
+ declare abstract class TranscriptionService {
51
+ abstract transcribeFile(options: TranscribeFileOptions): Promise<string>;
52
+ }
53
+
54
+ interface AgentRunnerRunRequest {
55
+ threadId: string;
56
+ agent: AbstractAgent;
57
+ input: RunAgentInput;
58
+ }
59
+ interface AgentRunnerConnectRequest {
60
+ threadId: string;
61
+ }
62
+ interface AgentRunnerIsRunningRequest {
63
+ threadId: string;
64
+ }
65
+ interface AgentRunnerStopRequest {
66
+ threadId: string;
67
+ }
68
+ declare abstract class AgentRunner {
69
+ abstract run(request: AgentRunnerRunRequest): Observable<BaseEvent>;
70
+ abstract connect(request: AgentRunnerConnectRequest): Observable<BaseEvent>;
71
+ abstract isRunning(request: AgentRunnerIsRunningRequest): Promise<boolean>;
72
+ abstract stop(request: AgentRunnerStopRequest): Promise<boolean | undefined>;
73
+ }
74
+
75
+ declare const VERSION: string;
76
+ /**
77
+ * Options used to construct a `CopilotRuntime` instance.
78
+ */
79
+ interface CopilotRuntimeOptions {
80
+ /** Map of available agents (loaded lazily is fine). */
81
+ agents: MaybePromise<NonEmptyRecord<Record<string, AbstractAgent>>>;
82
+ /** The runner to use for running agents. */
83
+ runner?: AgentRunner;
84
+ /** Optional transcription service for audio processing. */
85
+ transcriptionService?: TranscriptionService;
86
+ /** Optional *before* middleware – callback function or webhook URL. */
87
+ beforeRequestMiddleware?: BeforeRequestMiddleware;
88
+ /** Optional *after* middleware – callback function or webhook URL. */
89
+ afterRequestMiddleware?: AfterRequestMiddleware;
90
+ }
91
+ /**
92
+ * Central runtime object passed to all request handlers.
93
+ */
94
+ declare class CopilotRuntime {
95
+ agents: CopilotRuntimeOptions["agents"];
96
+ transcriptionService: CopilotRuntimeOptions["transcriptionService"];
97
+ beforeRequestMiddleware: CopilotRuntimeOptions["beforeRequestMiddleware"];
98
+ afterRequestMiddleware: CopilotRuntimeOptions["afterRequestMiddleware"];
99
+ runner: AgentRunner;
100
+ constructor({ agents, transcriptionService, beforeRequestMiddleware, afterRequestMiddleware, runner, }: CopilotRuntimeOptions);
101
+ }
102
+
103
+ interface CopilotEndpointParams {
104
+ runtime: CopilotRuntime;
105
+ basePath: string;
106
+ }
107
+ type CopilotEndpointContext = {
108
+ Variables: {
109
+ modifiedRequest?: Request;
110
+ };
111
+ };
112
+ declare function createCopilotEndpoint({ runtime, basePath, }: CopilotEndpointParams): hono_hono_base.HonoBase<CopilotEndpointContext, {
113
+ [x: `${string}/*`]: {};
114
+ } & {
115
+ [x: `${string}/agent/:agentId/run`]: {
116
+ $post: {
117
+ input: {
118
+ param: {
119
+ agentId: string;
120
+ };
121
+ };
122
+ output: {};
123
+ outputFormat: string;
124
+ status: hono_utils_http_status.StatusCode;
125
+ };
126
+ };
127
+ } & {
128
+ [x: `${string}/agent/:agentId/connect`]: {
129
+ $post: {
130
+ input: {
131
+ param: {
132
+ agentId: string;
133
+ };
134
+ };
135
+ output: {};
136
+ outputFormat: string;
137
+ status: hono_utils_http_status.StatusCode;
138
+ };
139
+ };
140
+ } & {
141
+ [x: `${string}/info`]: {
142
+ $get: {
143
+ input: {};
144
+ output: {};
145
+ outputFormat: string;
146
+ status: hono_utils_http_status.StatusCode;
147
+ };
148
+ };
149
+ } & {
150
+ [x: `${string}/transcribe`]: {
151
+ $post: {
152
+ input: {};
153
+ output: {};
154
+ outputFormat: string;
155
+ status: hono_utils_http_status.StatusCode;
156
+ };
157
+ };
158
+ }, string>;
159
+
160
+ declare class InMemoryAgentRunner extends AgentRunner {
161
+ private convertMessageToEvents;
162
+ run(request: AgentRunnerRunRequest): Observable<BaseEvent>;
163
+ connect(request: AgentRunnerConnectRequest): Observable<BaseEvent>;
164
+ isRunning(request: AgentRunnerIsRunningRequest): Promise<boolean>;
165
+ stop(_request: AgentRunnerStopRequest): Promise<boolean | undefined>;
166
+ }
167
+
168
+ interface SqliteAgentRunnerOptions {
169
+ dbPath?: string;
170
+ }
171
+ declare class SqliteAgentRunner extends AgentRunner {
172
+ private db;
173
+ constructor(options?: SqliteAgentRunnerOptions);
174
+ private convertMessageToEvents;
175
+ private initializeSchema;
176
+ private storeRun;
177
+ private getHistoricRuns;
178
+ private getLatestRunId;
179
+ private setRunState;
180
+ private getRunState;
181
+ run(request: AgentRunnerRunRequest): Observable<BaseEvent>;
182
+ connect(request: AgentRunnerConnectRequest): Observable<BaseEvent>;
183
+ isRunning(request: AgentRunnerIsRunningRequest): Promise<boolean>;
184
+ stop(_request: AgentRunnerStopRequest): Promise<boolean | undefined>;
185
+ /**
186
+ * Close the database connection (for cleanup)
187
+ */
188
+ close(): void;
189
+ }
190
+
191
+ interface AgentDatabase {
192
+ agent_runs: {
193
+ id: Generated<number>;
194
+ thread_id: string;
195
+ run_id: string;
196
+ parent_run_id: string | null;
197
+ events: string;
198
+ input: string;
199
+ created_at: number;
200
+ version: number;
201
+ };
202
+ run_state: {
203
+ thread_id: string;
204
+ is_running: number;
205
+ current_run_id: string | null;
206
+ server_id: string | null;
207
+ updated_at: number;
208
+ };
209
+ schema_version: {
210
+ version: number;
211
+ applied_at: number;
212
+ };
213
+ }
214
+ interface EnterpriseAgentRunnerOptions {
215
+ kysely: Kysely<AgentDatabase>;
216
+ redis: Redis;
217
+ redisSub?: Redis;
218
+ streamRetentionMs?: number;
219
+ streamActiveTTLMs?: number;
220
+ lockTTLMs?: number;
221
+ serverId?: string;
222
+ }
223
+ declare class EnterpriseAgentRunner extends AgentRunner {
224
+ private db;
225
+ redis: Redis;
226
+ redisSub: Redis;
227
+ private serverId;
228
+ private streamRetentionMs;
229
+ private streamActiveTTLMs;
230
+ private lockTTLMs;
231
+ constructor(options: EnterpriseAgentRunnerOptions);
232
+ run(request: AgentRunnerRunRequest): Observable<BaseEvent>;
233
+ connect(request: AgentRunnerConnectRequest): Observable<BaseEvent>;
234
+ isRunning(request: AgentRunnerIsRunningRequest): Promise<boolean>;
235
+ stop(request: AgentRunnerStopRequest): Promise<boolean>;
236
+ private convertMessageToEvents;
237
+ private initializeSchema;
238
+ private storeRun;
239
+ private getHistoricRuns;
240
+ private setRunState;
241
+ close(): Promise<void>;
242
+ private generateServerId;
243
+ }
244
+
245
+ export { CopilotRuntime, type CopilotRuntimeOptions, EnterpriseAgentRunner, type EnterpriseAgentRunnerOptions, InMemoryAgentRunner, SqliteAgentRunner, VERSION, createCopilotEndpoint };