@copilotkit/runtime 1.2.1 → 1.2.2-feat-runtime-remote-actions.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/CHANGELOG.md +26 -0
- package/__snapshots__/schema/schema.graphql +41 -0
- package/dist/{chunk-YMUS43FR.mjs → chunk-2N45GS3P.mjs} +2 -2
- package/dist/{chunk-URMISMK2.mjs → chunk-73NMP3DI.mjs} +2 -2
- package/dist/{chunk-736EEICU.mjs → chunk-BJ2LVHWA.mjs} +3 -3
- package/dist/{chunk-DMO6FA25.mjs → chunk-T6O5FSTK.mjs} +2 -2
- package/dist/{chunk-GEIBJJQ4.mjs → chunk-TBZGOJJX.mjs} +14 -2
- package/dist/chunk-TBZGOJJX.mjs.map +1 -0
- package/dist/{chunk-DYF5MUAH.mjs → chunk-X5QBBMCJ.mjs} +2 -2
- package/dist/{chunk-Q5ZTE7WH.mjs → chunk-XROLDARH.mjs} +786 -158
- package/dist/chunk-XROLDARH.mjs.map +1 -0
- package/dist/chunk-ZNZGATLW.mjs +260 -0
- package/dist/chunk-ZNZGATLW.mjs.map +1 -0
- package/dist/{shared-c5362338.d.ts → copilot-runtime-d427e991.d.ts} +65 -38
- package/dist/graphql/types/converted/index.d.ts +1 -1
- package/dist/graphql/types/converted/index.js +13 -0
- package/dist/graphql/types/converted/index.js.map +1 -1
- package/dist/graphql/types/converted/index.mjs +3 -1
- package/dist/{index-aa091e3c.d.ts → index-0476e4f7.d.ts} +24 -2
- package/dist/{index-13aa818e.d.ts → index-079752b9.d.ts} +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.js +982 -245
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8 -8
- package/dist/{langserve-a54438c6.d.ts → langserve-d6073a3b.d.ts} +24 -11
- package/dist/lib/index.d.ts +7 -7
- package/dist/lib/index.js +982 -245
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/index.mjs +8 -8
- package/dist/lib/integrations/index.d.ts +6 -6
- package/dist/lib/integrations/index.js +437 -182
- package/dist/lib/integrations/index.js.map +1 -1
- package/dist/lib/integrations/index.mjs +6 -6
- package/dist/lib/integrations/nest/index.d.ts +5 -5
- package/dist/lib/integrations/nest/index.js +437 -182
- package/dist/lib/integrations/nest/index.js.map +1 -1
- package/dist/lib/integrations/nest/index.mjs +4 -4
- package/dist/lib/integrations/node-express/index.d.ts +5 -5
- package/dist/lib/integrations/node-express/index.js +437 -182
- package/dist/lib/integrations/node-express/index.js.map +1 -1
- package/dist/lib/integrations/node-express/index.mjs +4 -4
- package/dist/lib/integrations/node-http/index.d.ts +5 -5
- package/dist/lib/integrations/node-http/index.js +437 -182
- package/dist/lib/integrations/node-http/index.js.map +1 -1
- package/dist/lib/integrations/node-http/index.mjs +3 -3
- package/dist/service-adapters/index.d.ts +3 -3
- package/dist/service-adapters/index.js.map +1 -1
- package/dist/service-adapters/index.mjs +3 -3
- package/package.json +7 -5
- package/src/agents/langgraph/event-source.ts +222 -0
- package/src/agents/langgraph/events.ts +309 -0
- package/src/graphql/inputs/agent-session.input.ts +13 -0
- package/src/graphql/inputs/agent-state.input.ts +10 -0
- package/src/graphql/inputs/generate-copilot-response.input.ts +11 -0
- package/src/graphql/inputs/message.input.ts +30 -0
- package/src/graphql/resolvers/copilot.resolver.ts +56 -12
- package/src/graphql/types/converted/index.ts +15 -0
- package/src/graphql/types/copilot-response.type.ts +29 -0
- package/src/graphql/types/enums.ts +1 -0
- package/src/lib/index.ts +1 -1
- package/src/lib/integrations/shared.ts +1 -1
- package/src/lib/runtime/copilot-runtime.ts +360 -0
- package/src/lib/runtime/remote-actions.ts +241 -0
- package/src/service-adapters/conversion.ts +16 -0
- package/src/service-adapters/events.ts +101 -19
- package/dist/chunk-GEIBJJQ4.mjs.map +0 -1
- package/dist/chunk-PB24CCIJ.mjs +0 -158
- package/dist/chunk-PB24CCIJ.mjs.map +0 -1
- package/dist/chunk-Q5ZTE7WH.mjs.map +0 -1
- package/src/lib/copilot-runtime.ts +0 -231
- /package/dist/{chunk-YMUS43FR.mjs.map → chunk-2N45GS3P.mjs.map} +0 -0
- /package/dist/{chunk-URMISMK2.mjs.map → chunk-73NMP3DI.mjs.map} +0 -0
- /package/dist/{chunk-736EEICU.mjs.map → chunk-BJ2LVHWA.mjs.map} +0 -0
- /package/dist/{chunk-DMO6FA25.mjs.map → chunk-T6O5FSTK.mjs.map} +0 -0
- /package/dist/{chunk-DYF5MUAH.mjs.map → chunk-X5QBBMCJ.mjs.map} +0 -0
|
@@ -32,7 +32,13 @@ import {
|
|
|
32
32
|
MessageStreamInterruptedResponse,
|
|
33
33
|
UnknownErrorResponse,
|
|
34
34
|
} from "../../utils";
|
|
35
|
-
import {
|
|
35
|
+
import {
|
|
36
|
+
ActionExecutionMessage,
|
|
37
|
+
AgentStateMessage,
|
|
38
|
+
Message,
|
|
39
|
+
ResultMessage,
|
|
40
|
+
TextMessage,
|
|
41
|
+
} from "../types/converted";
|
|
36
42
|
import telemetry from "../../lib/telemetry-client";
|
|
37
43
|
import { randomId } from "@copilotkit/shared";
|
|
38
44
|
|
|
@@ -49,8 +55,6 @@ const invokeGuardrails = async ({
|
|
|
49
55
|
onResult: (result: GuardrailsResult) => void;
|
|
50
56
|
onError: (err: Error) => void;
|
|
51
57
|
}) => {
|
|
52
|
-
console.log("invokeGuardrails.baseUrl", baseUrl);
|
|
53
|
-
|
|
54
58
|
if (
|
|
55
59
|
data.messages.length &&
|
|
56
60
|
data.messages[data.messages.length - 1].textMessage?.role === MessageRole.user
|
|
@@ -116,14 +120,14 @@ export class CopilotResolver {
|
|
|
116
120
|
let logger = ctx.logger.child({ component: "CopilotResolver.generateCopilotResponse" });
|
|
117
121
|
logger.debug({ data }, "Generating Copilot response");
|
|
118
122
|
|
|
119
|
-
const copilotRuntime = ctx._copilotkit.runtime;
|
|
120
|
-
const serviceAdapter = ctx._copilotkit.serviceAdapter;
|
|
121
|
-
|
|
122
123
|
if (properties) {
|
|
123
124
|
logger.debug("Properties provided, merging with context properties");
|
|
124
125
|
ctx.properties = { ...ctx.properties, ...properties };
|
|
125
126
|
}
|
|
126
127
|
|
|
128
|
+
const copilotRuntime = ctx._copilotkit.runtime;
|
|
129
|
+
const serviceAdapter = ctx._copilotkit.serviceAdapter;
|
|
130
|
+
|
|
127
131
|
let copilotCloudPublicApiKey: string | null = null;
|
|
128
132
|
let copilotCloudBaseUrl: string;
|
|
129
133
|
|
|
@@ -169,17 +173,20 @@ export class CopilotResolver {
|
|
|
169
173
|
eventSource,
|
|
170
174
|
threadId = randomId(),
|
|
171
175
|
runId,
|
|
172
|
-
|
|
173
|
-
|
|
176
|
+
serverSideActions,
|
|
177
|
+
actionInputsWithoutAgents,
|
|
178
|
+
} = await copilotRuntime.processRuntimeRequest({
|
|
174
179
|
serviceAdapter,
|
|
175
180
|
messages: data.messages,
|
|
176
181
|
actions: data.frontend.actions,
|
|
177
182
|
threadId: data.threadId,
|
|
178
183
|
runId: data.runId,
|
|
179
184
|
publicApiKey: undefined,
|
|
180
|
-
properties: ctx.properties || {},
|
|
181
185
|
outputMessagesPromise,
|
|
186
|
+
graphqlContext: ctx,
|
|
182
187
|
forwardedParameters: data.forwardedParameters,
|
|
188
|
+
agentSession: data.agentSession,
|
|
189
|
+
agentStates: data.agentStates,
|
|
183
190
|
url: data.frontend.url,
|
|
184
191
|
});
|
|
185
192
|
|
|
@@ -247,9 +254,14 @@ export class CopilotResolver {
|
|
|
247
254
|
|
|
248
255
|
// run and process the event stream
|
|
249
256
|
const eventStream = eventSource
|
|
250
|
-
.
|
|
251
|
-
|
|
257
|
+
.processRuntimeEvents({
|
|
258
|
+
serverSideActions,
|
|
252
259
|
guardrailsResult$: data.cloud?.guardrails ? guardrailsResult$ : null,
|
|
260
|
+
actionInputsWithoutAgents: actionInputsWithoutAgents.filter(
|
|
261
|
+
// TODO-AGENTS: do not exclude ALL server side actions
|
|
262
|
+
(action) =>
|
|
263
|
+
!serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
|
|
264
|
+
),
|
|
253
265
|
})
|
|
254
266
|
.pipe(
|
|
255
267
|
// shareReplay() ensures that later subscribers will see the whole stream instead of
|
|
@@ -281,7 +293,6 @@ export class CopilotResolver {
|
|
|
281
293
|
const streamingTextStatus = new Subject<typeof MessageStatusUnion>();
|
|
282
294
|
|
|
283
295
|
const messageId = randomId();
|
|
284
|
-
|
|
285
296
|
// push the new message
|
|
286
297
|
pushMessage({
|
|
287
298
|
id: messageId,
|
|
@@ -433,6 +444,39 @@ export class CopilotResolver {
|
|
|
433
444
|
}),
|
|
434
445
|
);
|
|
435
446
|
break;
|
|
447
|
+
////////////////////////////////
|
|
448
|
+
// AgentStateMessage
|
|
449
|
+
////////////////////////////////
|
|
450
|
+
case RuntimeEventTypes.AgentStateMessage:
|
|
451
|
+
logger.debug({ event }, "Agent message event received");
|
|
452
|
+
pushMessage({
|
|
453
|
+
id: randomId(),
|
|
454
|
+
status: new SuccessMessageStatus(),
|
|
455
|
+
threadId: event.threadId,
|
|
456
|
+
agentName: event.agentName,
|
|
457
|
+
nodeName: event.nodeName,
|
|
458
|
+
runId: event.runId,
|
|
459
|
+
active: event.active,
|
|
460
|
+
state: event.state,
|
|
461
|
+
running: event.running,
|
|
462
|
+
role: MessageRole.assistant,
|
|
463
|
+
createdAt: new Date(),
|
|
464
|
+
});
|
|
465
|
+
outputMessages.push(
|
|
466
|
+
plainToInstance(AgentStateMessage, {
|
|
467
|
+
id: randomId(),
|
|
468
|
+
threadId: event.threadId,
|
|
469
|
+
agentName: event.agentName,
|
|
470
|
+
nodeName: event.nodeName,
|
|
471
|
+
runId: event.runId,
|
|
472
|
+
active: event.active,
|
|
473
|
+
state: event.state,
|
|
474
|
+
running: event.running,
|
|
475
|
+
role: MessageRole.assistant,
|
|
476
|
+
createdAt: new Date(),
|
|
477
|
+
}),
|
|
478
|
+
);
|
|
479
|
+
break;
|
|
436
480
|
}
|
|
437
481
|
},
|
|
438
482
|
error: (err) => {
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
ActionExecutionMessageInput,
|
|
3
3
|
ResultMessageInput,
|
|
4
4
|
TextMessageInput,
|
|
5
|
+
AgentStateMessageInput,
|
|
5
6
|
} from "../../inputs/message.input";
|
|
6
7
|
import { BaseMessage } from "../base";
|
|
7
8
|
import { ActionExecutionScope, MessageRole } from "../enums";
|
|
@@ -27,3 +28,17 @@ export class ResultMessage extends BaseMessage implements ResultMessageInput {
|
|
|
27
28
|
actionName: string;
|
|
28
29
|
result: string;
|
|
29
30
|
}
|
|
31
|
+
|
|
32
|
+
export class AgentStateMessage
|
|
33
|
+
extends BaseMessage
|
|
34
|
+
implements Omit<AgentStateMessageInput, "state">
|
|
35
|
+
{
|
|
36
|
+
threadId: string;
|
|
37
|
+
agentName: string;
|
|
38
|
+
nodeName: string;
|
|
39
|
+
runId: string;
|
|
40
|
+
active: boolean;
|
|
41
|
+
role: MessageRole;
|
|
42
|
+
state: any;
|
|
43
|
+
running: boolean;
|
|
44
|
+
}
|
|
@@ -11,6 +11,8 @@ import { ResponseStatusUnion } from "./response-status.type";
|
|
|
11
11
|
return ActionExecutionMessageOutput;
|
|
12
12
|
} else if (value.hasOwnProperty("result")) {
|
|
13
13
|
return ResultMessageOutput;
|
|
14
|
+
} else if (value.hasOwnProperty("state")) {
|
|
15
|
+
return AgentStateMessageOutput;
|
|
14
16
|
}
|
|
15
17
|
return undefined;
|
|
16
18
|
},
|
|
@@ -59,6 +61,33 @@ export class ResultMessageOutput {
|
|
|
59
61
|
result: string;
|
|
60
62
|
}
|
|
61
63
|
|
|
64
|
+
@ObjectType({ implements: BaseMessageOutput })
|
|
65
|
+
export class AgentStateMessageOutput {
|
|
66
|
+
@Field(() => String)
|
|
67
|
+
threadId: string;
|
|
68
|
+
|
|
69
|
+
@Field(() => String)
|
|
70
|
+
agentName: string;
|
|
71
|
+
|
|
72
|
+
@Field(() => String)
|
|
73
|
+
nodeName: string;
|
|
74
|
+
|
|
75
|
+
@Field(() => String)
|
|
76
|
+
runId: string;
|
|
77
|
+
|
|
78
|
+
@Field(() => Boolean)
|
|
79
|
+
active: boolean;
|
|
80
|
+
|
|
81
|
+
@Field(() => MessageRole)
|
|
82
|
+
role: MessageRole;
|
|
83
|
+
|
|
84
|
+
@Field(() => String)
|
|
85
|
+
state: string;
|
|
86
|
+
|
|
87
|
+
@Field(() => Boolean)
|
|
88
|
+
running: boolean;
|
|
89
|
+
}
|
|
90
|
+
|
|
62
91
|
@ObjectType()
|
|
63
92
|
export class CopilotResponse {
|
|
64
93
|
@Field(() => String)
|
package/src/lib/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export * from "./copilot-runtime";
|
|
1
|
+
export * from "./runtime/copilot-runtime";
|
|
2
2
|
export * from "../service-adapters/openai/openai-adapter";
|
|
3
3
|
export * from "../service-adapters/langchain/langchain-adapter";
|
|
4
4
|
export * from "../service-adapters/google/google-genai-adapter";
|
|
@@ -2,7 +2,7 @@ import { YogaInitialContext } from "graphql-yoga";
|
|
|
2
2
|
import { buildSchemaSync } from "type-graphql";
|
|
3
3
|
import { CopilotResolver } from "../../graphql/resolvers/copilot.resolver";
|
|
4
4
|
import { useDeferStream } from "@graphql-yoga/plugin-defer-stream";
|
|
5
|
-
import { CopilotRuntime } from "../copilot-runtime";
|
|
5
|
+
import { CopilotRuntime } from "../runtime/copilot-runtime";
|
|
6
6
|
import { CopilotServiceAdapter } from "../../service-adapters";
|
|
7
7
|
import { CopilotCloudOptions } from "../cloud";
|
|
8
8
|
import { LogLevel, createLogger } from "../../lib/logger";
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <Callout type="info">
|
|
3
|
+
* This is the reference for the `CopilotRuntime` class. For more information and example code snippets, please see [Concept: Copilot Runtime](/concepts/copilot-runtime).
|
|
4
|
+
* </Callout>
|
|
5
|
+
*
|
|
6
|
+
* ## Usage
|
|
7
|
+
*
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { CopilotRuntime } from "@copilotkit/runtime";
|
|
10
|
+
*
|
|
11
|
+
* const copilotKit = new CopilotRuntime();
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { Action, actionParametersToJsonSchema, Parameter, randomId } from "@copilotkit/shared";
|
|
16
|
+
import { RemoteChain, RemoteChainParameters, CopilotServiceAdapter } from "../../service-adapters";
|
|
17
|
+
import { MessageInput } from "../../graphql/inputs/message.input";
|
|
18
|
+
import { ActionInput } from "../../graphql/inputs/action.input";
|
|
19
|
+
import { RuntimeEventSource } from "../../service-adapters/events";
|
|
20
|
+
import { convertGqlInputToMessages } from "../../service-adapters/conversion";
|
|
21
|
+
import { AgentStateMessage, Message } from "../../graphql/types/converted";
|
|
22
|
+
import { ForwardedParametersInput } from "../../graphql/inputs/forwarded-parameters.input";
|
|
23
|
+
import {
|
|
24
|
+
setupRemoteActions,
|
|
25
|
+
RemoteActionDefinition,
|
|
26
|
+
LangGraphAgentAction,
|
|
27
|
+
isLangGraphAgentAction,
|
|
28
|
+
} from "./remote-actions";
|
|
29
|
+
import { GraphQLContext } from "../integrations/shared";
|
|
30
|
+
import { AgentSessionInput } from "../../graphql/inputs/agent-session.input";
|
|
31
|
+
import { from } from "rxjs";
|
|
32
|
+
import { AgentStateInput } from "../../graphql/inputs/agent-state.input";
|
|
33
|
+
|
|
34
|
+
interface CopilotRuntimeRequest {
|
|
35
|
+
serviceAdapter: CopilotServiceAdapter;
|
|
36
|
+
messages: MessageInput[];
|
|
37
|
+
actions: ActionInput[];
|
|
38
|
+
agentSession?: AgentSessionInput;
|
|
39
|
+
agentStates?: AgentStateInput[];
|
|
40
|
+
outputMessagesPromise: Promise<Message[]>;
|
|
41
|
+
threadId?: string;
|
|
42
|
+
runId?: string;
|
|
43
|
+
publicApiKey?: string;
|
|
44
|
+
graphqlContext: GraphQLContext;
|
|
45
|
+
forwardedParameters?: ForwardedParametersInput;
|
|
46
|
+
url?: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface CopilotRuntimeResponse {
|
|
50
|
+
threadId: string;
|
|
51
|
+
runId?: string;
|
|
52
|
+
eventSource: RuntimeEventSource;
|
|
53
|
+
serverSideActions: Action<any>[];
|
|
54
|
+
actionInputsWithoutAgents: ActionInput[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
type ActionsConfiguration<T extends Parameter[] | [] = []> =
|
|
58
|
+
| Action<T>[]
|
|
59
|
+
| ((ctx: { properties: any; url?: string }) => Action<T>[]);
|
|
60
|
+
|
|
61
|
+
interface OnBeforeRequestOptions {
|
|
62
|
+
threadId?: string;
|
|
63
|
+
runId?: string;
|
|
64
|
+
inputMessages: Message[];
|
|
65
|
+
properties: any;
|
|
66
|
+
url?: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
type OnBeforeRequestHandler = (options: OnBeforeRequestOptions) => void | Promise<void>;
|
|
70
|
+
|
|
71
|
+
interface OnAfterRequestOptions {
|
|
72
|
+
threadId: string;
|
|
73
|
+
runId?: string;
|
|
74
|
+
inputMessages: Message[];
|
|
75
|
+
outputMessages: Message[];
|
|
76
|
+
properties: any;
|
|
77
|
+
url?: string;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
type OnAfterRequestHandler = (options: OnAfterRequestOptions) => void | Promise<void>;
|
|
81
|
+
|
|
82
|
+
interface Middleware {
|
|
83
|
+
/**
|
|
84
|
+
* A function that is called before the request is processed.
|
|
85
|
+
*/
|
|
86
|
+
onBeforeRequest?: OnBeforeRequestHandler;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* A function that is called after the request is processed.
|
|
90
|
+
*/
|
|
91
|
+
onAfterRequest?: OnAfterRequestHandler;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []> {
|
|
95
|
+
/**
|
|
96
|
+
* Middleware to be used by the runtime.
|
|
97
|
+
*
|
|
98
|
+
* ```ts
|
|
99
|
+
* onBeforeRequest: (options: {
|
|
100
|
+
* threadId?: string;
|
|
101
|
+
* runId?: string;
|
|
102
|
+
* inputMessages: Message[];
|
|
103
|
+
* properties: any;
|
|
104
|
+
* }) => void | Promise<void>;
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* ```ts
|
|
108
|
+
* onAfterRequest: (options: {
|
|
109
|
+
* threadId?: string;
|
|
110
|
+
* runId?: string;
|
|
111
|
+
* inputMessages: Message[];
|
|
112
|
+
* outputMessages: Message[];
|
|
113
|
+
* properties: any;
|
|
114
|
+
* }) => void | Promise<void>;
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
middleware?: Middleware;
|
|
118
|
+
|
|
119
|
+
/*
|
|
120
|
+
* A list of server side actions that can be executed.
|
|
121
|
+
*/
|
|
122
|
+
actions?: ActionsConfiguration<T>;
|
|
123
|
+
|
|
124
|
+
/*
|
|
125
|
+
* A list of remote actions that can be executed.
|
|
126
|
+
*/
|
|
127
|
+
remoteActions?: RemoteActionDefinition[];
|
|
128
|
+
|
|
129
|
+
/*
|
|
130
|
+
* An array of LangServer URLs.
|
|
131
|
+
*/
|
|
132
|
+
langserve?: RemoteChainParameters[];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
136
|
+
public actions: ActionsConfiguration<T>;
|
|
137
|
+
private remoteActionDefinitions: RemoteActionDefinition[];
|
|
138
|
+
private langserve: Promise<Action<any>>[] = [];
|
|
139
|
+
private onBeforeRequest?: OnBeforeRequestHandler;
|
|
140
|
+
private onAfterRequest?: OnAfterRequestHandler;
|
|
141
|
+
|
|
142
|
+
constructor(params?: CopilotRuntimeConstructorParams<T>) {
|
|
143
|
+
this.actions = params?.actions || [];
|
|
144
|
+
|
|
145
|
+
for (const chain of params?.langserve || []) {
|
|
146
|
+
const remoteChain = new RemoteChain(chain);
|
|
147
|
+
this.langserve.push(remoteChain.toAction());
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
this.remoteActionDefinitions = params?.remoteActions || [];
|
|
151
|
+
|
|
152
|
+
this.onBeforeRequest = params?.middleware?.onBeforeRequest;
|
|
153
|
+
this.onAfterRequest = params?.middleware?.onAfterRequest;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async processRuntimeRequest(request: CopilotRuntimeRequest): Promise<CopilotRuntimeResponse> {
|
|
157
|
+
const {
|
|
158
|
+
serviceAdapter,
|
|
159
|
+
messages: rawMessages,
|
|
160
|
+
actions: clientSideActionsInput,
|
|
161
|
+
threadId,
|
|
162
|
+
runId,
|
|
163
|
+
outputMessagesPromise,
|
|
164
|
+
graphqlContext,
|
|
165
|
+
forwardedParameters,
|
|
166
|
+
agentSession,
|
|
167
|
+
url,
|
|
168
|
+
} = request;
|
|
169
|
+
|
|
170
|
+
if (agentSession) {
|
|
171
|
+
return this.processAgentRequest(request);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const messages = rawMessages.filter((message) => !message.agentStateMessage);
|
|
175
|
+
|
|
176
|
+
const inputMessages = convertGqlInputToMessages(messages);
|
|
177
|
+
const serverSideActions = await this.getServerSideActions(request);
|
|
178
|
+
|
|
179
|
+
const serverSideActionsInput: ActionInput[] = serverSideActions.map((action) => ({
|
|
180
|
+
name: action.name,
|
|
181
|
+
description: action.description,
|
|
182
|
+
jsonSchema: JSON.stringify(actionParametersToJsonSchema(action.parameters)),
|
|
183
|
+
}));
|
|
184
|
+
|
|
185
|
+
const actionInputs = flattenToolCallsNoDuplicates([
|
|
186
|
+
...serverSideActionsInput,
|
|
187
|
+
...clientSideActionsInput,
|
|
188
|
+
]);
|
|
189
|
+
|
|
190
|
+
await this.onBeforeRequest?.({
|
|
191
|
+
threadId,
|
|
192
|
+
runId,
|
|
193
|
+
inputMessages,
|
|
194
|
+
properties: graphqlContext.properties,
|
|
195
|
+
url,
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
const eventSource = new RuntimeEventSource();
|
|
200
|
+
|
|
201
|
+
const result = await serviceAdapter.process({
|
|
202
|
+
messages: inputMessages,
|
|
203
|
+
actions: actionInputs,
|
|
204
|
+
threadId,
|
|
205
|
+
runId,
|
|
206
|
+
eventSource,
|
|
207
|
+
forwardedParameters,
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
outputMessagesPromise
|
|
211
|
+
.then((outputMessages) => {
|
|
212
|
+
this.onAfterRequest?.({
|
|
213
|
+
threadId: result.threadId,
|
|
214
|
+
runId: result.runId,
|
|
215
|
+
inputMessages,
|
|
216
|
+
outputMessages,
|
|
217
|
+
properties: graphqlContext.properties,
|
|
218
|
+
url,
|
|
219
|
+
});
|
|
220
|
+
})
|
|
221
|
+
.catch((_error) => {});
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
threadId: result.threadId,
|
|
225
|
+
runId: result.runId,
|
|
226
|
+
eventSource,
|
|
227
|
+
serverSideActions,
|
|
228
|
+
actionInputsWithoutAgents: actionInputs.filter(
|
|
229
|
+
(action) =>
|
|
230
|
+
// TODO-AGENTS: do not exclude ALL server side actions
|
|
231
|
+
!serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
|
|
232
|
+
// !isLangGraphAgentAction(
|
|
233
|
+
// serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
|
|
234
|
+
// ),
|
|
235
|
+
),
|
|
236
|
+
};
|
|
237
|
+
} catch (error) {
|
|
238
|
+
console.error("Error getting response:", error);
|
|
239
|
+
throw error;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
private async processAgentRequest(
|
|
244
|
+
request: CopilotRuntimeRequest,
|
|
245
|
+
): Promise<CopilotRuntimeResponse> {
|
|
246
|
+
const { messages: rawMessages, outputMessagesPromise, graphqlContext, agentSession } = request;
|
|
247
|
+
const { threadId = randomId(), agentName, nodeName } = agentSession;
|
|
248
|
+
const serverSideActions = await this.getServerSideActions(request);
|
|
249
|
+
|
|
250
|
+
const messages = convertGqlInputToMessages(rawMessages);
|
|
251
|
+
|
|
252
|
+
const agent = serverSideActions.find(
|
|
253
|
+
(action) => action.name === agentName && isLangGraphAgentAction(action),
|
|
254
|
+
) as LangGraphAgentAction;
|
|
255
|
+
|
|
256
|
+
if (!agent) {
|
|
257
|
+
throw new Error(`Agent ${agentName} not found`);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const serverSideActionsInput: ActionInput[] = serverSideActions
|
|
261
|
+
.filter((action) => !isLangGraphAgentAction(action))
|
|
262
|
+
.map((action) => ({
|
|
263
|
+
name: action.name,
|
|
264
|
+
description: action.description,
|
|
265
|
+
jsonSchema: JSON.stringify(actionParametersToJsonSchema(action.parameters)),
|
|
266
|
+
}));
|
|
267
|
+
|
|
268
|
+
const actionInputsWithoutAgents = flattenToolCallsNoDuplicates([
|
|
269
|
+
...serverSideActionsInput,
|
|
270
|
+
...request.actions,
|
|
271
|
+
]);
|
|
272
|
+
|
|
273
|
+
await this.onBeforeRequest?.({
|
|
274
|
+
threadId,
|
|
275
|
+
runId: undefined,
|
|
276
|
+
inputMessages: messages,
|
|
277
|
+
properties: graphqlContext.properties,
|
|
278
|
+
});
|
|
279
|
+
try {
|
|
280
|
+
const eventSource = new RuntimeEventSource();
|
|
281
|
+
const stream = await agent.langGraphAgentHandler({
|
|
282
|
+
name: agentName,
|
|
283
|
+
threadId,
|
|
284
|
+
nodeName,
|
|
285
|
+
actionInputsWithoutAgents,
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
eventSource.stream(async (eventStream$) => {
|
|
289
|
+
from(stream).subscribe({
|
|
290
|
+
next: (event) => eventStream$.next(event),
|
|
291
|
+
error: (err) => console.error("Error in stream", err),
|
|
292
|
+
complete: () => eventStream$.complete(),
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
outputMessagesPromise
|
|
297
|
+
.then((outputMessages) => {
|
|
298
|
+
this.onAfterRequest?.({
|
|
299
|
+
threadId,
|
|
300
|
+
runId: undefined,
|
|
301
|
+
inputMessages: messages,
|
|
302
|
+
outputMessages,
|
|
303
|
+
properties: graphqlContext.properties,
|
|
304
|
+
});
|
|
305
|
+
})
|
|
306
|
+
.catch((_error) => {});
|
|
307
|
+
|
|
308
|
+
return {
|
|
309
|
+
threadId,
|
|
310
|
+
runId: undefined,
|
|
311
|
+
eventSource,
|
|
312
|
+
serverSideActions: [],
|
|
313
|
+
actionInputsWithoutAgents,
|
|
314
|
+
};
|
|
315
|
+
} catch (error) {
|
|
316
|
+
console.error("Error getting response:", error);
|
|
317
|
+
throw error;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
private async getServerSideActions(request: CopilotRuntimeRequest): Promise<Action<any>[]> {
|
|
322
|
+
const { messages: rawMessages, graphqlContext, agentStates, url } = request;
|
|
323
|
+
const inputMessages = convertGqlInputToMessages(rawMessages);
|
|
324
|
+
const langserveFunctions: Action<any>[] = [];
|
|
325
|
+
|
|
326
|
+
for (const chainPromise of this.langserve) {
|
|
327
|
+
try {
|
|
328
|
+
const chain = await chainPromise;
|
|
329
|
+
langserveFunctions.push(chain);
|
|
330
|
+
} catch (error) {
|
|
331
|
+
console.error("Error loading langserve chain:", error);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
const remoteActions = await setupRemoteActions({
|
|
335
|
+
remoteActionDefinitions: this.remoteActionDefinitions,
|
|
336
|
+
graphqlContext,
|
|
337
|
+
messages: inputMessages,
|
|
338
|
+
agentStates,
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
const configuredActions =
|
|
342
|
+
typeof this.actions === "function"
|
|
343
|
+
? this.actions({ properties: graphqlContext.properties, url })
|
|
344
|
+
: this.actions;
|
|
345
|
+
|
|
346
|
+
return [...configuredActions, ...langserveFunctions, ...remoteActions];
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
export function flattenToolCallsNoDuplicates(toolsByPriority: ActionInput[]): ActionInput[] {
|
|
351
|
+
let allTools: ActionInput[] = [];
|
|
352
|
+
const allToolNames: string[] = [];
|
|
353
|
+
for (const tool of toolsByPriority) {
|
|
354
|
+
if (!allToolNames.includes(tool.name)) {
|
|
355
|
+
allTools.push(tool);
|
|
356
|
+
allToolNames.push(tool.name);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return allTools;
|
|
360
|
+
}
|