@copilotkit/runtime 0.0.0-mme-load-agent-state-20250117154700
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/.eslintrc.js +7 -0
- package/CHANGELOG.md +929 -0
- package/README.md +46 -0
- package/__snapshots__/schema/schema.graphql +306 -0
- package/dist/chunk-44O2JGUY.mjs +12 -0
- package/dist/chunk-44O2JGUY.mjs.map +1 -0
- package/dist/chunk-4BWLNVK4.mjs +80 -0
- package/dist/chunk-4BWLNVK4.mjs.map +1 -0
- package/dist/chunk-4QJA7OT2.mjs +3395 -0
- package/dist/chunk-4QJA7OT2.mjs.map +1 -0
- package/dist/chunk-4YJIXJLO.mjs +25 -0
- package/dist/chunk-4YJIXJLO.mjs.map +1 -0
- package/dist/chunk-67KK2GZ5.mjs +3765 -0
- package/dist/chunk-67KK2GZ5.mjs.map +1 -0
- package/dist/chunk-7BOVBWKI.mjs +25 -0
- package/dist/chunk-7BOVBWKI.mjs.map +1 -0
- package/dist/chunk-B5KHNAW5.mjs +25 -0
- package/dist/chunk-B5KHNAW5.mjs.map +1 -0
- package/dist/chunk-CLGKEUOA.mjs +1408 -0
- package/dist/chunk-CLGKEUOA.mjs.map +1 -0
- package/dist/chunk-D2WLFQS6.mjs +43 -0
- package/dist/chunk-D2WLFQS6.mjs.map +1 -0
- package/dist/chunk-DFOKBSIS.mjs +1 -0
- package/dist/chunk-DFOKBSIS.mjs.map +1 -0
- package/dist/chunk-DKLATJGV.mjs +25 -0
- package/dist/chunk-DKLATJGV.mjs.map +1 -0
- package/dist/chunk-FYONHPZL.mjs +3397 -0
- package/dist/chunk-FYONHPZL.mjs.map +1 -0
- package/dist/chunk-HNUNXFTW.mjs +129 -0
- package/dist/chunk-HNUNXFTW.mjs.map +1 -0
- package/dist/chunk-OKUXS4SE.mjs +25 -0
- package/dist/chunk-OKUXS4SE.mjs.map +1 -0
- package/dist/chunk-P4PPTGPJ.mjs +25 -0
- package/dist/chunk-P4PPTGPJ.mjs.map +1 -0
- package/dist/chunk-RFF5IIZJ.mjs +66 -0
- package/dist/chunk-RFF5IIZJ.mjs.map +1 -0
- package/dist/chunk-U3V2BCGI.mjs +152 -0
- package/dist/chunk-U3V2BCGI.mjs.map +1 -0
- package/dist/chunk-U7EKYV47.mjs +80 -0
- package/dist/chunk-U7EKYV47.mjs.map +1 -0
- package/dist/chunk-XXYYCH4X.mjs +80 -0
- package/dist/chunk-XXYYCH4X.mjs.map +1 -0
- package/dist/chunk-YT7A6V5T.mjs +1420 -0
- package/dist/chunk-YT7A6V5T.mjs.map +1 -0
- package/dist/copilot-runtime-36700e00.d.ts +196 -0
- package/dist/copilot-runtime-8c442d65.d.ts +209 -0
- package/dist/graphql/types/base/index.d.ts +6 -0
- package/dist/graphql/types/base/index.js +63 -0
- package/dist/graphql/types/base/index.js.map +1 -0
- package/dist/graphql/types/base/index.mjs +8 -0
- package/dist/graphql/types/base/index.mjs.map +1 -0
- package/dist/graphql/types/converted/index.d.ts +2 -0
- package/dist/graphql/types/converted/index.js +187 -0
- package/dist/graphql/types/converted/index.js.map +1 -0
- package/dist/graphql/types/converted/index.mjs +17 -0
- package/dist/graphql/types/converted/index.mjs.map +1 -0
- package/dist/groq-adapter-696b5d29.d.ts +281 -0
- package/dist/groq-adapter-7a82cd22.d.ts +301 -0
- package/dist/index-a7f37670.d.ts +103 -0
- package/dist/index-cc2b17be.d.ts +87 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +5597 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +76 -0
- package/dist/index.mjs.map +1 -0
- package/dist/langserve-9125a12e.d.ts +176 -0
- package/dist/langserve-e308c437.d.ts +209 -0
- package/dist/lib/cloud/index.d.ts +6 -0
- package/dist/lib/cloud/index.js +18 -0
- package/dist/lib/cloud/index.js.map +1 -0
- package/dist/lib/cloud/index.mjs +1 -0
- package/dist/lib/cloud/index.mjs.map +1 -0
- package/dist/lib/index.d.ts +20 -0
- package/dist/lib/index.js +5256 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/index.mjs +58 -0
- package/dist/lib/index.mjs.map +1 -0
- package/dist/lib/integrations/index.d.ts +33 -0
- package/dist/lib/integrations/index.js +2488 -0
- package/dist/lib/integrations/index.js.map +1 -0
- package/dist/lib/integrations/index.mjs +34 -0
- package/dist/lib/integrations/index.mjs.map +1 -0
- package/dist/lib/integrations/nest/index.d.ts +14 -0
- package/dist/lib/integrations/nest/index.js +2397 -0
- package/dist/lib/integrations/nest/index.js.map +1 -0
- package/dist/lib/integrations/nest/index.mjs +13 -0
- package/dist/lib/integrations/nest/index.mjs.map +1 -0
- package/dist/lib/integrations/node-express/index.d.ts +14 -0
- package/dist/lib/integrations/node-express/index.js +2397 -0
- package/dist/lib/integrations/node-express/index.js.map +1 -0
- package/dist/lib/integrations/node-express/index.mjs +13 -0
- package/dist/lib/integrations/node-express/index.mjs.map +1 -0
- package/dist/lib/integrations/node-http/index.d.ts +14 -0
- package/dist/lib/integrations/node-http/index.js +2383 -0
- package/dist/lib/integrations/node-http/index.js.map +1 -0
- package/dist/lib/integrations/node-http/index.mjs +12 -0
- package/dist/lib/integrations/node-http/index.mjs.map +1 -0
- package/dist/service-adapters/index.d.ts +84 -0
- package/dist/service-adapters/index.js +1460 -0
- package/dist/service-adapters/index.js.map +1 -0
- package/dist/service-adapters/index.mjs +26 -0
- package/dist/service-adapters/index.mjs.map +1 -0
- package/dist/utils/index.d.ts +49 -0
- package/dist/utils/index.js +174 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +12 -0
- package/dist/utils/index.mjs.map +1 -0
- package/jest.config.js +5 -0
- package/package.json +85 -0
- package/scripts/generate-gql-schema.ts +13 -0
- package/src/agents/langgraph/event-source.ts +287 -0
- package/src/agents/langgraph/events.ts +338 -0
- package/src/graphql/inputs/action.input.ts +16 -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/cloud-guardrails.input.ts +16 -0
- package/src/graphql/inputs/cloud.input.ts +8 -0
- package/src/graphql/inputs/context-property.input.ts +10 -0
- package/src/graphql/inputs/custom-property.input.ts +15 -0
- package/src/graphql/inputs/extensions.input.ts +21 -0
- package/src/graphql/inputs/forwarded-parameters.input.ts +22 -0
- package/src/graphql/inputs/frontend.input.ts +14 -0
- package/src/graphql/inputs/generate-copilot-response.input.ts +51 -0
- package/src/graphql/inputs/load-agent-state.input.ts +10 -0
- package/src/graphql/inputs/message.input.ts +92 -0
- package/src/graphql/resolvers/copilot.resolver.ts +561 -0
- package/src/graphql/resolvers/state.resolver.ts +23 -0
- package/src/graphql/types/agents-response.type.ts +19 -0
- package/src/graphql/types/base/index.ts +10 -0
- package/src/graphql/types/converted/index.ts +136 -0
- package/src/graphql/types/copilot-response.type.ts +117 -0
- package/src/graphql/types/enums.ts +37 -0
- package/src/graphql/types/extensions-response.type.ts +23 -0
- package/src/graphql/types/guardrails-result.type.ts +20 -0
- package/src/graphql/types/load-agent-state-response.type.ts +17 -0
- package/src/graphql/types/message-status.type.ts +40 -0
- package/src/graphql/types/response-status.type.ts +66 -0
- package/src/index.ts +4 -0
- package/src/lib/cloud/index.ts +4 -0
- package/src/lib/index.ts +8 -0
- package/src/lib/integrations/index.ts +6 -0
- package/src/lib/integrations/nest/index.ts +17 -0
- package/src/lib/integrations/nextjs/app-router.ts +40 -0
- package/src/lib/integrations/nextjs/pages-router.ts +49 -0
- package/src/lib/integrations/node-express/index.ts +17 -0
- package/src/lib/integrations/node-http/index.ts +34 -0
- package/src/lib/integrations/shared.ts +110 -0
- package/src/lib/logger.ts +28 -0
- package/src/lib/runtime/copilot-runtime.ts +571 -0
- package/src/lib/runtime/remote-action-constructors.ts +304 -0
- package/src/lib/runtime/remote-actions.ts +174 -0
- package/src/lib/runtime/remote-lg-action.ts +669 -0
- package/src/lib/telemetry-client.ts +52 -0
- package/src/service-adapters/anthropic/anthropic-adapter.ts +204 -0
- package/src/service-adapters/anthropic/utils.ts +144 -0
- package/src/service-adapters/conversion.ts +64 -0
- package/src/service-adapters/events.ts +424 -0
- package/src/service-adapters/experimental/empty/empty-adapter.ts +33 -0
- package/src/service-adapters/experimental/ollama/ollama-adapter.ts +79 -0
- package/src/service-adapters/google/google-genai-adapter.ts +39 -0
- package/src/service-adapters/groq/groq-adapter.ts +173 -0
- package/src/service-adapters/index.ts +16 -0
- package/src/service-adapters/langchain/langchain-adapter.ts +106 -0
- package/src/service-adapters/langchain/langserve.ts +87 -0
- package/src/service-adapters/langchain/types.ts +14 -0
- package/src/service-adapters/langchain/utils.ts +306 -0
- package/src/service-adapters/openai/openai-adapter.ts +211 -0
- package/src/service-adapters/openai/openai-assistant-adapter.ts +315 -0
- package/src/service-adapters/openai/utils.ts +161 -0
- package/src/service-adapters/service-adapter.ts +34 -0
- package/src/service-adapters/unify/unify-adapter.ts +144 -0
- package/src/utils/failed-response-status-reasons.ts +48 -0
- package/src/utils/index.ts +1 -0
- package/tsconfig.json +11 -0
- package/tsup.config.ts +16 -0
- package/typedoc.json +4 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { YogaInitialContext } from "graphql-yoga";
|
|
2
|
+
import { buildSchemaSync } from "type-graphql";
|
|
3
|
+
import { CopilotResolver } from "../../graphql/resolvers/copilot.resolver";
|
|
4
|
+
import { useDeferStream } from "@graphql-yoga/plugin-defer-stream";
|
|
5
|
+
import { CopilotRuntime } from "../runtime/copilot-runtime";
|
|
6
|
+
import { CopilotServiceAdapter } from "../../service-adapters";
|
|
7
|
+
import { CopilotCloudOptions } from "../cloud";
|
|
8
|
+
import { LogLevel, createLogger } from "../../lib/logger";
|
|
9
|
+
import { createYoga } from "graphql-yoga";
|
|
10
|
+
import telemetry from "../telemetry-client";
|
|
11
|
+
import { StateResolver } from "../../graphql/resolvers/state.resolver";
|
|
12
|
+
|
|
13
|
+
const logger = createLogger();
|
|
14
|
+
|
|
15
|
+
type AnyPrimitive = string | boolean | number | null;
|
|
16
|
+
export type CopilotRequestContextProperties = Record<
|
|
17
|
+
string,
|
|
18
|
+
AnyPrimitive | Record<string, AnyPrimitive>
|
|
19
|
+
>;
|
|
20
|
+
|
|
21
|
+
export type GraphQLContext = YogaInitialContext & {
|
|
22
|
+
_copilotkit: CreateCopilotRuntimeServerOptions;
|
|
23
|
+
properties: CopilotRequestContextProperties;
|
|
24
|
+
logger: typeof logger;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export interface CreateCopilotRuntimeServerOptions {
|
|
28
|
+
runtime: CopilotRuntime<any>;
|
|
29
|
+
serviceAdapter: CopilotServiceAdapter;
|
|
30
|
+
endpoint: string;
|
|
31
|
+
baseUrl?: string;
|
|
32
|
+
cloud?: CopilotCloudOptions;
|
|
33
|
+
properties?: CopilotRequestContextProperties;
|
|
34
|
+
logLevel?: LogLevel;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function createContext(
|
|
38
|
+
initialContext: YogaInitialContext,
|
|
39
|
+
copilotKitContext: CreateCopilotRuntimeServerOptions,
|
|
40
|
+
contextLogger: typeof logger,
|
|
41
|
+
properties: CopilotRequestContextProperties = {},
|
|
42
|
+
): Promise<Partial<GraphQLContext>> {
|
|
43
|
+
logger.debug({ copilotKitContext }, "Creating GraphQL context");
|
|
44
|
+
const ctx: GraphQLContext = {
|
|
45
|
+
...initialContext,
|
|
46
|
+
_copilotkit: {
|
|
47
|
+
...copilotKitContext,
|
|
48
|
+
},
|
|
49
|
+
properties: { ...properties },
|
|
50
|
+
logger: contextLogger,
|
|
51
|
+
};
|
|
52
|
+
return ctx;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function buildSchema(
|
|
56
|
+
options: {
|
|
57
|
+
emitSchemaFile?: string;
|
|
58
|
+
} = {},
|
|
59
|
+
) {
|
|
60
|
+
logger.debug("Building GraphQL schema...");
|
|
61
|
+
const schema = buildSchemaSync({
|
|
62
|
+
resolvers: [CopilotResolver, StateResolver],
|
|
63
|
+
emitSchemaFile: options.emitSchemaFile,
|
|
64
|
+
});
|
|
65
|
+
logger.debug("GraphQL schema built successfully");
|
|
66
|
+
return schema;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export type CommonConfig = {
|
|
70
|
+
logging: typeof logger;
|
|
71
|
+
schema: ReturnType<typeof buildSchema>;
|
|
72
|
+
plugins: Parameters<typeof createYoga>[0]["plugins"];
|
|
73
|
+
context: (ctx: YogaInitialContext) => Promise<Partial<GraphQLContext>>;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export function getCommonConfig(options: CreateCopilotRuntimeServerOptions): CommonConfig {
|
|
77
|
+
const logLevel = (process.env.LOG_LEVEL as LogLevel) || (options.logLevel as LogLevel) || "error";
|
|
78
|
+
const logger = createLogger({ level: logLevel, component: "getCommonConfig" });
|
|
79
|
+
|
|
80
|
+
const contextLogger = createLogger({ level: logLevel });
|
|
81
|
+
|
|
82
|
+
if (options.cloud) {
|
|
83
|
+
telemetry.setCloudConfiguration({
|
|
84
|
+
publicApiKey: options.cloud.publicApiKey,
|
|
85
|
+
baseUrl: options.cloud.baseUrl,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (options.properties?._copilotkit) {
|
|
90
|
+
telemetry.setGlobalProperties({
|
|
91
|
+
_copilotkit: {
|
|
92
|
+
...(options.properties._copilotkit as Record<string, any>),
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
telemetry.setGlobalProperties({
|
|
98
|
+
runtime: {
|
|
99
|
+
serviceAdapter: options.serviceAdapter.constructor.name,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
logging: createLogger({ component: "Yoga GraphQL", level: logLevel }),
|
|
105
|
+
schema: buildSchema(),
|
|
106
|
+
plugins: [useDeferStream()],
|
|
107
|
+
context: (ctx: YogaInitialContext): Promise<Partial<GraphQLContext>> =>
|
|
108
|
+
createContext(ctx, options, contextLogger, options.properties),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import createPinoLogger from "pino";
|
|
2
|
+
import pretty from "pino-pretty";
|
|
3
|
+
|
|
4
|
+
export type LogLevel = "debug" | "info" | "warn" | "error";
|
|
5
|
+
|
|
6
|
+
export type CopilotRuntimeLogger = ReturnType<typeof createLogger>;
|
|
7
|
+
|
|
8
|
+
export function createLogger(options?: { level?: LogLevel; component?: string }) {
|
|
9
|
+
const { level, component } = options || {};
|
|
10
|
+
const stream = pretty({ colorize: true });
|
|
11
|
+
|
|
12
|
+
const logger = createPinoLogger(
|
|
13
|
+
{
|
|
14
|
+
level: process.env.LOG_LEVEL || level || "error",
|
|
15
|
+
redact: {
|
|
16
|
+
paths: ["pid", "hostname"],
|
|
17
|
+
remove: true,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
stream,
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
if (component) {
|
|
24
|
+
return logger.child({ component });
|
|
25
|
+
} else {
|
|
26
|
+
return logger;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,571 @@
|
|
|
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 {
|
|
17
|
+
CopilotServiceAdapter,
|
|
18
|
+
ExperimentalEmptyAdapter,
|
|
19
|
+
RemoteChain,
|
|
20
|
+
RemoteChainParameters,
|
|
21
|
+
} from "../../service-adapters";
|
|
22
|
+
import { MessageInput } from "../../graphql/inputs/message.input";
|
|
23
|
+
import { ActionInput } from "../../graphql/inputs/action.input";
|
|
24
|
+
import { RuntimeEventSource } from "../../service-adapters/events";
|
|
25
|
+
import { convertGqlInputToMessages } from "../../service-adapters/conversion";
|
|
26
|
+
import { Message } from "../../graphql/types/converted";
|
|
27
|
+
import { ForwardedParametersInput } from "../../graphql/inputs/forwarded-parameters.input";
|
|
28
|
+
import {
|
|
29
|
+
isLangGraphAgentAction,
|
|
30
|
+
LangGraphAgentAction,
|
|
31
|
+
EndpointType,
|
|
32
|
+
setupRemoteActions,
|
|
33
|
+
EndpointDefinition,
|
|
34
|
+
CopilotKitEndpoint,
|
|
35
|
+
LangGraphPlatformEndpoint,
|
|
36
|
+
} from "./remote-actions";
|
|
37
|
+
import { GraphQLContext } from "../integrations/shared";
|
|
38
|
+
import { AgentSessionInput } from "../../graphql/inputs/agent-session.input";
|
|
39
|
+
import { from } from "rxjs";
|
|
40
|
+
import { AgentStateInput } from "../../graphql/inputs/agent-state.input";
|
|
41
|
+
import { ActionInputAvailability } from "../../graphql/types/enums";
|
|
42
|
+
import { createHeaders } from "./remote-action-constructors";
|
|
43
|
+
import { Agent } from "../../graphql/types/agents-response.type";
|
|
44
|
+
import { ExtensionsInput } from "../../graphql/inputs/extensions.input";
|
|
45
|
+
import { ExtensionsResponse } from "../../graphql/types/extensions-response.type";
|
|
46
|
+
import { LoadAgentStateResponse } from "../../graphql/types/load-agent-state-response.type";
|
|
47
|
+
import { Client as LangGraphClient } from "@langchain/langgraph-sdk";
|
|
48
|
+
import { langchainMessagesToCopilotKit } from "./remote-lg-action";
|
|
49
|
+
|
|
50
|
+
interface CopilotRuntimeRequest {
|
|
51
|
+
serviceAdapter: CopilotServiceAdapter;
|
|
52
|
+
messages: MessageInput[];
|
|
53
|
+
actions: ActionInput[];
|
|
54
|
+
agentSession?: AgentSessionInput;
|
|
55
|
+
agentStates?: AgentStateInput[];
|
|
56
|
+
outputMessagesPromise: Promise<Message[]>;
|
|
57
|
+
threadId?: string;
|
|
58
|
+
runId?: string;
|
|
59
|
+
publicApiKey?: string;
|
|
60
|
+
graphqlContext: GraphQLContext;
|
|
61
|
+
forwardedParameters?: ForwardedParametersInput;
|
|
62
|
+
url?: string;
|
|
63
|
+
extensions?: ExtensionsInput;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface CopilotRuntimeResponse {
|
|
67
|
+
threadId: string;
|
|
68
|
+
runId?: string;
|
|
69
|
+
eventSource: RuntimeEventSource;
|
|
70
|
+
serverSideActions: Action<any>[];
|
|
71
|
+
actionInputsWithoutAgents: ActionInput[];
|
|
72
|
+
extensions?: ExtensionsResponse;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
type ActionsConfiguration<T extends Parameter[] | [] = []> =
|
|
76
|
+
| Action<T>[]
|
|
77
|
+
| ((ctx: { properties: any; url?: string }) => Action<T>[]);
|
|
78
|
+
|
|
79
|
+
interface OnBeforeRequestOptions {
|
|
80
|
+
threadId?: string;
|
|
81
|
+
runId?: string;
|
|
82
|
+
inputMessages: Message[];
|
|
83
|
+
properties: any;
|
|
84
|
+
url?: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
type OnBeforeRequestHandler = (options: OnBeforeRequestOptions) => void | Promise<void>;
|
|
88
|
+
|
|
89
|
+
interface OnAfterRequestOptions {
|
|
90
|
+
threadId: string;
|
|
91
|
+
runId?: string;
|
|
92
|
+
inputMessages: Message[];
|
|
93
|
+
outputMessages: Message[];
|
|
94
|
+
properties: any;
|
|
95
|
+
url?: string;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
type OnAfterRequestHandler = (options: OnAfterRequestOptions) => void | Promise<void>;
|
|
99
|
+
|
|
100
|
+
interface Middleware {
|
|
101
|
+
/**
|
|
102
|
+
* A function that is called before the request is processed.
|
|
103
|
+
*/
|
|
104
|
+
onBeforeRequest?: OnBeforeRequestHandler;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* A function that is called after the request is processed.
|
|
108
|
+
*/
|
|
109
|
+
onAfterRequest?: OnAfterRequestHandler;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
type AgentWithEndpoint = Agent & { endpoint: EndpointDefinition };
|
|
113
|
+
|
|
114
|
+
export interface CopilotRuntimeConstructorParams<T extends Parameter[] | [] = []> {
|
|
115
|
+
/**
|
|
116
|
+
* Middleware to be used by the runtime.
|
|
117
|
+
*
|
|
118
|
+
* ```ts
|
|
119
|
+
* onBeforeRequest: (options: {
|
|
120
|
+
* threadId?: string;
|
|
121
|
+
* runId?: string;
|
|
122
|
+
* inputMessages: Message[];
|
|
123
|
+
* properties: any;
|
|
124
|
+
* }) => void | Promise<void>;
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* ```ts
|
|
128
|
+
* onAfterRequest: (options: {
|
|
129
|
+
* threadId?: string;
|
|
130
|
+
* runId?: string;
|
|
131
|
+
* inputMessages: Message[];
|
|
132
|
+
* outputMessages: Message[];
|
|
133
|
+
* properties: any;
|
|
134
|
+
* }) => void | Promise<void>;
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
middleware?: Middleware;
|
|
138
|
+
|
|
139
|
+
/*
|
|
140
|
+
* A list of server side actions that can be executed.
|
|
141
|
+
*/
|
|
142
|
+
actions?: ActionsConfiguration<T>;
|
|
143
|
+
|
|
144
|
+
/*
|
|
145
|
+
* Deprecated: Use `remoteEndpoints`.
|
|
146
|
+
*/
|
|
147
|
+
remoteActions?: CopilotKitEndpoint[];
|
|
148
|
+
|
|
149
|
+
/*
|
|
150
|
+
* A list of remote actions that can be executed.
|
|
151
|
+
*/
|
|
152
|
+
remoteEndpoints?: EndpointDefinition[];
|
|
153
|
+
|
|
154
|
+
/*
|
|
155
|
+
* An array of LangServer URLs.
|
|
156
|
+
*/
|
|
157
|
+
langserve?: RemoteChainParameters[];
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
161
|
+
public actions: ActionsConfiguration<T>;
|
|
162
|
+
public remoteEndpointDefinitions: EndpointDefinition[];
|
|
163
|
+
private langserve: Promise<Action<any>>[] = [];
|
|
164
|
+
private onBeforeRequest?: OnBeforeRequestHandler;
|
|
165
|
+
private onAfterRequest?: OnAfterRequestHandler;
|
|
166
|
+
|
|
167
|
+
constructor(params?: CopilotRuntimeConstructorParams<T>) {
|
|
168
|
+
this.actions = params?.actions || [];
|
|
169
|
+
|
|
170
|
+
for (const chain of params?.langserve || []) {
|
|
171
|
+
const remoteChain = new RemoteChain(chain);
|
|
172
|
+
this.langserve.push(remoteChain.toAction());
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
this.remoteEndpointDefinitions = params?.remoteEndpoints ?? params?.remoteActions ?? [];
|
|
176
|
+
|
|
177
|
+
this.onBeforeRequest = params?.middleware?.onBeforeRequest;
|
|
178
|
+
this.onAfterRequest = params?.middleware?.onAfterRequest;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async processRuntimeRequest(request: CopilotRuntimeRequest): Promise<CopilotRuntimeResponse> {
|
|
182
|
+
const {
|
|
183
|
+
serviceAdapter,
|
|
184
|
+
messages: rawMessages,
|
|
185
|
+
actions: clientSideActionsInput,
|
|
186
|
+
threadId,
|
|
187
|
+
runId,
|
|
188
|
+
outputMessagesPromise,
|
|
189
|
+
graphqlContext,
|
|
190
|
+
forwardedParameters,
|
|
191
|
+
agentSession,
|
|
192
|
+
url,
|
|
193
|
+
extensions,
|
|
194
|
+
} = request;
|
|
195
|
+
|
|
196
|
+
const eventSource = new RuntimeEventSource();
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
if (agentSession) {
|
|
200
|
+
return await this.processAgentRequest(request);
|
|
201
|
+
}
|
|
202
|
+
if (serviceAdapter instanceof ExperimentalEmptyAdapter) {
|
|
203
|
+
// TODO: use CPK error here
|
|
204
|
+
throw new Error(`Invalid adapter configuration: ExperimentalEmptyAdapter is only meant to be used with agent lock mode.
|
|
205
|
+
For non-agent components like useCopilotChatSuggestions, CopilotTextarea, or CopilotTask,
|
|
206
|
+
please use an LLM adapter instead.`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const messages = rawMessages.filter((message) => !message.agentStateMessage);
|
|
210
|
+
|
|
211
|
+
const inputMessages = convertGqlInputToMessages(messages);
|
|
212
|
+
const serverSideActions = await this.getServerSideActions(request);
|
|
213
|
+
|
|
214
|
+
const serverSideActionsInput: ActionInput[] = serverSideActions.map((action) => ({
|
|
215
|
+
name: action.name,
|
|
216
|
+
description: action.description,
|
|
217
|
+
jsonSchema: JSON.stringify(actionParametersToJsonSchema(action.parameters)),
|
|
218
|
+
}));
|
|
219
|
+
|
|
220
|
+
const actionInputs = flattenToolCallsNoDuplicates([
|
|
221
|
+
...serverSideActionsInput,
|
|
222
|
+
...clientSideActionsInput.filter(
|
|
223
|
+
// Filter remote actions from CopilotKit core loop
|
|
224
|
+
(action) => action.available !== ActionInputAvailability.remote,
|
|
225
|
+
),
|
|
226
|
+
]);
|
|
227
|
+
|
|
228
|
+
await this.onBeforeRequest?.({
|
|
229
|
+
threadId,
|
|
230
|
+
runId,
|
|
231
|
+
inputMessages,
|
|
232
|
+
properties: graphqlContext.properties,
|
|
233
|
+
url,
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
const result = await serviceAdapter.process({
|
|
237
|
+
messages: inputMessages,
|
|
238
|
+
actions: actionInputs,
|
|
239
|
+
threadId,
|
|
240
|
+
runId,
|
|
241
|
+
eventSource,
|
|
242
|
+
forwardedParameters,
|
|
243
|
+
extensions,
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// for backwards compatibility, we deal with the case that no threadId is provided
|
|
247
|
+
// by the frontend, by using the threadId from the response
|
|
248
|
+
const nonEmptyThreadId = threadId ?? result.threadId;
|
|
249
|
+
|
|
250
|
+
outputMessagesPromise
|
|
251
|
+
.then((outputMessages) => {
|
|
252
|
+
this.onAfterRequest?.({
|
|
253
|
+
threadId: nonEmptyThreadId,
|
|
254
|
+
runId: result.runId,
|
|
255
|
+
inputMessages,
|
|
256
|
+
outputMessages,
|
|
257
|
+
properties: graphqlContext.properties,
|
|
258
|
+
url,
|
|
259
|
+
});
|
|
260
|
+
})
|
|
261
|
+
.catch((_error) => {});
|
|
262
|
+
|
|
263
|
+
return {
|
|
264
|
+
threadId: nonEmptyThreadId,
|
|
265
|
+
runId: result.runId,
|
|
266
|
+
eventSource,
|
|
267
|
+
serverSideActions,
|
|
268
|
+
actionInputsWithoutAgents: actionInputs.filter(
|
|
269
|
+
(action) =>
|
|
270
|
+
// TODO-AGENTS: do not exclude ALL server side actions
|
|
271
|
+
!serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
|
|
272
|
+
// !isLangGraphAgentAction(
|
|
273
|
+
// serverSideActions.find((serverSideAction) => serverSideAction.name == action.name),
|
|
274
|
+
// ),
|
|
275
|
+
),
|
|
276
|
+
extensions: result.extensions,
|
|
277
|
+
};
|
|
278
|
+
} catch (error) {
|
|
279
|
+
console.error("Error getting response:", error);
|
|
280
|
+
eventSource.sendErrorMessageToChat();
|
|
281
|
+
throw error;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
async discoverAgentsFromEndpoints(graphqlContext: GraphQLContext): Promise<AgentWithEndpoint[]> {
|
|
286
|
+
const headers = createHeaders(null, graphqlContext);
|
|
287
|
+
const agents = this.remoteEndpointDefinitions.reduce(
|
|
288
|
+
async (acc: Promise<Agent[]>, endpoint) => {
|
|
289
|
+
const agents = await acc;
|
|
290
|
+
if (endpoint.type === EndpointType.LangGraphPlatform) {
|
|
291
|
+
const client = new LangGraphClient({
|
|
292
|
+
apiUrl: endpoint.deploymentUrl,
|
|
293
|
+
apiKey: endpoint.langsmithApiKey,
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
const data: Array<{ assistant_id: string; graph_id: string }> =
|
|
297
|
+
await client.assistants.search();
|
|
298
|
+
|
|
299
|
+
const endpointAgents = (data ?? []).map((entry) => ({
|
|
300
|
+
name: entry.graph_id,
|
|
301
|
+
id: entry.assistant_id,
|
|
302
|
+
description: "",
|
|
303
|
+
endpoint,
|
|
304
|
+
}));
|
|
305
|
+
return [...agents, ...endpointAgents];
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
interface InfoResponse {
|
|
309
|
+
agents?: Array<{
|
|
310
|
+
name: string;
|
|
311
|
+
description: string;
|
|
312
|
+
}>;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const response = await fetch(`${(endpoint as CopilotKitEndpoint).url}/info`, {
|
|
316
|
+
method: "POST",
|
|
317
|
+
headers,
|
|
318
|
+
body: JSON.stringify({ properties: graphqlContext.properties }),
|
|
319
|
+
});
|
|
320
|
+
const data: InfoResponse = await response.json();
|
|
321
|
+
const endpointAgents = (data?.agents ?? []).map((agent) => ({
|
|
322
|
+
name: agent.name,
|
|
323
|
+
description: agent.description ?? "",
|
|
324
|
+
id: randomId(), // Required by Agent type
|
|
325
|
+
endpoint,
|
|
326
|
+
}));
|
|
327
|
+
return [...agents, ...endpointAgents];
|
|
328
|
+
},
|
|
329
|
+
Promise.resolve([]),
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
return agents;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
async loadAgentState(
|
|
336
|
+
graphqlContext: GraphQLContext,
|
|
337
|
+
threadId: string,
|
|
338
|
+
agentName: string,
|
|
339
|
+
): Promise<LoadAgentStateResponse> {
|
|
340
|
+
const agentsWithEndpoints = await this.discoverAgentsFromEndpoints(graphqlContext);
|
|
341
|
+
|
|
342
|
+
const agentWithEndpoint = agentsWithEndpoints.find((agent) => agent.name === agentName);
|
|
343
|
+
if (!agentWithEndpoint) {
|
|
344
|
+
throw new Error("Agent not found");
|
|
345
|
+
}
|
|
346
|
+
const headers = createHeaders(null, graphqlContext);
|
|
347
|
+
|
|
348
|
+
if (agentWithEndpoint.endpoint.type === EndpointType.LangGraphPlatform) {
|
|
349
|
+
const client = new LangGraphClient({
|
|
350
|
+
apiUrl: agentWithEndpoint.endpoint.deploymentUrl,
|
|
351
|
+
apiKey: agentWithEndpoint.endpoint.langsmithApiKey,
|
|
352
|
+
});
|
|
353
|
+
const state = (await client.threads.getState(threadId)).values as any;
|
|
354
|
+
|
|
355
|
+
if (Object.keys(state).length === 0) {
|
|
356
|
+
return {
|
|
357
|
+
threadId,
|
|
358
|
+
threadExists: false,
|
|
359
|
+
state: JSON.stringify({}),
|
|
360
|
+
messages: JSON.stringify([]),
|
|
361
|
+
};
|
|
362
|
+
} else {
|
|
363
|
+
console.log(state);
|
|
364
|
+
const { messages, ...stateWithoutMessages } = state;
|
|
365
|
+
const copilotkitMessages = langchainMessagesToCopilotKit(messages);
|
|
366
|
+
return {
|
|
367
|
+
threadId,
|
|
368
|
+
threadExists: true,
|
|
369
|
+
state: JSON.stringify(stateWithoutMessages),
|
|
370
|
+
messages: JSON.stringify(copilotkitMessages),
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
} else if (
|
|
374
|
+
agentWithEndpoint.endpoint.type === EndpointType.CopilotKit ||
|
|
375
|
+
!("type" in agentWithEndpoint.endpoint)
|
|
376
|
+
) {
|
|
377
|
+
const response = await fetch(
|
|
378
|
+
`${(agentWithEndpoint.endpoint as CopilotKitEndpoint).url}/agents/state`,
|
|
379
|
+
{
|
|
380
|
+
method: "POST",
|
|
381
|
+
headers,
|
|
382
|
+
body: JSON.stringify({
|
|
383
|
+
properties: graphqlContext.properties,
|
|
384
|
+
threadId,
|
|
385
|
+
name: agentName,
|
|
386
|
+
}),
|
|
387
|
+
},
|
|
388
|
+
);
|
|
389
|
+
const data: LoadAgentStateResponse = await response.json();
|
|
390
|
+
|
|
391
|
+
return {
|
|
392
|
+
...data,
|
|
393
|
+
state: JSON.stringify(data.state),
|
|
394
|
+
messages: JSON.stringify(data.messages),
|
|
395
|
+
};
|
|
396
|
+
} else {
|
|
397
|
+
throw new Error(`Unknown endpoint type: ${(agentWithEndpoint.endpoint as any).type}`);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
private async processAgentRequest(
|
|
402
|
+
request: CopilotRuntimeRequest,
|
|
403
|
+
): Promise<CopilotRuntimeResponse> {
|
|
404
|
+
const {
|
|
405
|
+
messages: rawMessages,
|
|
406
|
+
outputMessagesPromise,
|
|
407
|
+
graphqlContext,
|
|
408
|
+
agentSession,
|
|
409
|
+
threadId: threadIdFromRequest,
|
|
410
|
+
} = request;
|
|
411
|
+
const { agentName, nodeName } = agentSession;
|
|
412
|
+
|
|
413
|
+
// for backwards compatibility, deal with the case when no threadId is provided
|
|
414
|
+
const threadId = threadIdFromRequest ?? agentSession.threadId;
|
|
415
|
+
|
|
416
|
+
const serverSideActions = await this.getServerSideActions(request);
|
|
417
|
+
|
|
418
|
+
const messages = convertGqlInputToMessages(rawMessages);
|
|
419
|
+
|
|
420
|
+
const agent = serverSideActions.find(
|
|
421
|
+
(action) => action.name === agentName && isLangGraphAgentAction(action),
|
|
422
|
+
) as LangGraphAgentAction;
|
|
423
|
+
|
|
424
|
+
if (!agent) {
|
|
425
|
+
throw new Error(`Agent ${agentName} not found`);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
const serverSideActionsInput: ActionInput[] = serverSideActions
|
|
429
|
+
.filter((action) => !isLangGraphAgentAction(action))
|
|
430
|
+
.map((action) => ({
|
|
431
|
+
name: action.name,
|
|
432
|
+
description: action.description,
|
|
433
|
+
jsonSchema: JSON.stringify(actionParametersToJsonSchema(action.parameters)),
|
|
434
|
+
}));
|
|
435
|
+
|
|
436
|
+
const actionInputsWithoutAgents = flattenToolCallsNoDuplicates([
|
|
437
|
+
...serverSideActionsInput,
|
|
438
|
+
...request.actions,
|
|
439
|
+
]);
|
|
440
|
+
|
|
441
|
+
await this.onBeforeRequest?.({
|
|
442
|
+
threadId,
|
|
443
|
+
runId: undefined,
|
|
444
|
+
inputMessages: messages,
|
|
445
|
+
properties: graphqlContext.properties,
|
|
446
|
+
});
|
|
447
|
+
try {
|
|
448
|
+
const eventSource = new RuntimeEventSource();
|
|
449
|
+
const stream = await agent.langGraphAgentHandler({
|
|
450
|
+
name: agentName,
|
|
451
|
+
threadId,
|
|
452
|
+
nodeName,
|
|
453
|
+
actionInputsWithoutAgents,
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
eventSource.stream(async (eventStream$) => {
|
|
457
|
+
from(stream).subscribe({
|
|
458
|
+
next: (event) => eventStream$.next(event),
|
|
459
|
+
error: (err) => {
|
|
460
|
+
console.error("Error in stream", err);
|
|
461
|
+
eventStream$.error(err);
|
|
462
|
+
eventStream$.complete();
|
|
463
|
+
},
|
|
464
|
+
complete: () => eventStream$.complete(),
|
|
465
|
+
});
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
outputMessagesPromise
|
|
469
|
+
.then((outputMessages) => {
|
|
470
|
+
this.onAfterRequest?.({
|
|
471
|
+
threadId,
|
|
472
|
+
runId: undefined,
|
|
473
|
+
inputMessages: messages,
|
|
474
|
+
outputMessages,
|
|
475
|
+
properties: graphqlContext.properties,
|
|
476
|
+
});
|
|
477
|
+
})
|
|
478
|
+
.catch((_error) => {});
|
|
479
|
+
|
|
480
|
+
return {
|
|
481
|
+
threadId,
|
|
482
|
+
runId: undefined,
|
|
483
|
+
eventSource,
|
|
484
|
+
serverSideActions: [],
|
|
485
|
+
actionInputsWithoutAgents,
|
|
486
|
+
};
|
|
487
|
+
} catch (error) {
|
|
488
|
+
console.error("Error getting response:", error);
|
|
489
|
+
throw error;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
private async getServerSideActions(request: CopilotRuntimeRequest): Promise<Action<any>[]> {
|
|
494
|
+
const { messages: rawMessages, graphqlContext, agentStates, url } = request;
|
|
495
|
+
const inputMessages = convertGqlInputToMessages(rawMessages);
|
|
496
|
+
const langserveFunctions: Action<any>[] = [];
|
|
497
|
+
|
|
498
|
+
for (const chainPromise of this.langserve) {
|
|
499
|
+
try {
|
|
500
|
+
const chain = await chainPromise;
|
|
501
|
+
langserveFunctions.push(chain);
|
|
502
|
+
} catch (error) {
|
|
503
|
+
console.error("Error loading langserve chain:", error);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
const remoteEndpointDefinitions = this.remoteEndpointDefinitions.map(
|
|
508
|
+
(endpoint) =>
|
|
509
|
+
({
|
|
510
|
+
...endpoint,
|
|
511
|
+
type: resolveEndpointType(endpoint),
|
|
512
|
+
}) as EndpointDefinition,
|
|
513
|
+
);
|
|
514
|
+
|
|
515
|
+
const remoteActions = await setupRemoteActions({
|
|
516
|
+
remoteEndpointDefinitions,
|
|
517
|
+
graphqlContext,
|
|
518
|
+
messages: inputMessages,
|
|
519
|
+
agentStates,
|
|
520
|
+
frontendUrl: url,
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
const configuredActions =
|
|
524
|
+
typeof this.actions === "function"
|
|
525
|
+
? this.actions({ properties: graphqlContext.properties, url })
|
|
526
|
+
: this.actions;
|
|
527
|
+
|
|
528
|
+
return [...configuredActions, ...langserveFunctions, ...remoteActions];
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
export function flattenToolCallsNoDuplicates(toolsByPriority: ActionInput[]): ActionInput[] {
|
|
533
|
+
let allTools: ActionInput[] = [];
|
|
534
|
+
const allToolNames: string[] = [];
|
|
535
|
+
for (const tool of toolsByPriority) {
|
|
536
|
+
if (!allToolNames.includes(tool.name)) {
|
|
537
|
+
allTools.push(tool);
|
|
538
|
+
allToolNames.push(tool.name);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
return allTools;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// The two functions below are "factory functions", meant to create the action objects that adhere to the expected interfaces
|
|
545
|
+
export function copilotKitEndpoint(config: Omit<CopilotKitEndpoint, "type">): CopilotKitEndpoint {
|
|
546
|
+
return {
|
|
547
|
+
...config,
|
|
548
|
+
type: EndpointType.CopilotKit,
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
export function langGraphPlatformEndpoint(
|
|
553
|
+
config: Omit<LangGraphPlatformEndpoint, "type">,
|
|
554
|
+
): LangGraphPlatformEndpoint {
|
|
555
|
+
return {
|
|
556
|
+
...config,
|
|
557
|
+
type: EndpointType.LangGraphPlatform,
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
export function resolveEndpointType(endpoint: EndpointDefinition) {
|
|
562
|
+
if (!endpoint.type) {
|
|
563
|
+
if ("langsmithApiKey" in endpoint && "deploymentUrl" in endpoint && "agents" in endpoint) {
|
|
564
|
+
return EndpointType.LangGraphPlatform;
|
|
565
|
+
} else {
|
|
566
|
+
return EndpointType.CopilotKit;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
return endpoint.type;
|
|
571
|
+
}
|