@copilotkit/runtime
Version:
<img src="https://github.com/user-attachments/assets/0a6b64d9-e193-4940-a3f6-60334ac34084" alt="banner" style="border-radius: 12px; border: 2px solid #d6d4fa;" />
452 lines (450 loc) • 22.8 kB
JavaScript
require("reflect-metadata");
const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
const require_enums = require('../types/enums.cjs');
const require_decorateMetadata = require('../../_virtual/_@oxc-project_runtime@0.112.0/helpers/decorateMetadata.cjs');
const require_decorate = require('../../_virtual/_@oxc-project_runtime@0.112.0/helpers/decorate.cjs');
const require_message_status_type = require('../types/message-status.type.cjs');
const require_response_status_type = require('../types/response-status.type.cjs');
const require_copilot_response_type = require('../types/copilot-response.type.cjs');
const require_meta_events_type = require('../types/meta-events.type.cjs');
const require_generate_copilot_response_input = require('../inputs/generate-copilot-response.input.cjs');
const require_index = require('../types/converted/index.cjs');
const require_events = require('../../service-adapters/events.cjs');
const require_failed_response_status_reasons = require('../../utils/failed-response-status-reasons.cjs');
const require_telemetry_client = require('../../lib/telemetry-client.cjs');
const require_resolve_message_id = require('./resolve-message-id.cjs');
const require_agents_response_type = require('../types/agents-response.type.cjs');
const require_events$1 = require('../../agents/langgraph/events.cjs');
const require_decorateParam = require('../../_virtual/_@oxc-project_runtime@0.112.0/helpers/decorateParam.cjs');
let _copilotkit_shared = require("@copilotkit/shared");
let type_graphql = require("type-graphql");
let rxjs = require("rxjs");
let graphql_scalars = require("graphql-scalars");
let graphql_yoga = require("graphql-yoga");
let class_transformer = require("class-transformer");
let graphql = require("graphql");
//#region src/graphql/resolvers/copilot.resolver.ts
var _ref;
const invokeGuardrails = async ({ baseUrl, copilotCloudPublicApiKey, data, onResult, onError }) => {
if (data.messages.length && data.messages[data.messages.length - 1].textMessage?.role === require_enums.MessageRole.user) {
const messages = data.messages.filter((m) => m.textMessage !== void 0 && (m.textMessage.role === require_enums.MessageRole.user || m.textMessage.role === require_enums.MessageRole.assistant)).map((m) => ({
role: m.textMessage.role,
content: m.textMessage.content
}));
const lastMessage = messages[messages.length - 1];
const restOfMessages = messages.slice(0, -1);
const body = {
input: lastMessage.content,
validTopics: data.cloud.guardrails.inputValidationRules.allowList,
invalidTopics: data.cloud.guardrails.inputValidationRules.denyList,
messages: restOfMessages
};
const guardrailsResult = await fetch(`${baseUrl}/guardrails/validate`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CopilotCloud-Public-API-Key": copilotCloudPublicApiKey
},
body: JSON.stringify(body)
});
if (guardrailsResult.ok) onResult(await guardrailsResult.json());
else onError(await guardrailsResult.json());
}
};
let CopilotResolver = class CopilotResolver {
async hello() {
return "Hello World";
}
async availableAgents(ctx) {
let logger = ctx.logger.child({ component: "CopilotResolver.availableAgents" });
logger.debug("Processing");
const agentsWithEndpoints = [];
logger.debug("Event source created, creating response");
return { agents: agentsWithEndpoints.map(({ endpoint, ...agentWithoutEndpoint }) => agentWithoutEndpoint) };
}
async generateCopilotResponse(ctx, data, properties) {
require_telemetry_client.default.capture("oss.runtime.copilot_request_created", {
"cloud.guardrails.enabled": data.cloud?.guardrails !== void 0,
requestType: data.metadata.requestType,
"cloud.api_key_provided": !!ctx.request.headers.get("x-copilotcloud-public-api-key"),
...ctx.request.headers.get("x-copilotcloud-public-api-key") ? { "cloud.public_api_key": ctx.request.headers.get("x-copilotcloud-public-api-key") } : {},
...ctx._copilotkit.baseUrl ? { "cloud.base_url": ctx._copilotkit.baseUrl } : { "cloud.base_url": "https://api.cloud.copilotkit.ai" }
});
let logger = ctx.logger.child({ component: "CopilotResolver.generateCopilotResponse" });
logger.debug({ data }, "Generating Copilot response");
if (properties) {
logger.debug("Properties provided, merging with context properties");
ctx.properties = {
...ctx.properties,
...properties
};
}
ctx._copilotkit.runtime;
ctx._copilotkit.serviceAdapter;
let copilotCloudPublicApiKey = null;
let copilotCloudBaseUrl;
const publicApiKeyFromHeaders = ctx.request.headers.get("x-copilotcloud-public-api-key");
if (publicApiKeyFromHeaders) copilotCloudPublicApiKey = publicApiKeyFromHeaders;
if (data.cloud) {
logger = logger.child({ cloud: true });
logger.debug("Cloud configuration provided, checking for public API key in headers");
if (!copilotCloudPublicApiKey) {
logger.error("Public API key not found in headers");
throw new graphql.GraphQLError("X-CopilotCloud-Public-API-Key header is required");
}
if (process.env.COPILOT_CLOUD_BASE_URL) copilotCloudBaseUrl = process.env.COPILOT_CLOUD_BASE_URL;
else if (ctx._copilotkit.cloud?.baseUrl) copilotCloudBaseUrl = ctx._copilotkit.cloud?.baseUrl;
else copilotCloudBaseUrl = "https://api.cloud.copilotkit.ai";
logger = logger.child({ copilotCloudBaseUrl });
}
logger.debug("Setting up subjects");
const responseStatus$ = new rxjs.ReplaySubject();
const interruptStreaming$ = new rxjs.ReplaySubject();
const guardrailsResult$ = new rxjs.ReplaySubject();
let outputMessages = [];
let resolveOutputMessagesPromise;
let rejectOutputMessagesPromise;
new Promise((resolve, reject) => {
resolveOutputMessagesPromise = resolve;
rejectOutputMessagesPromise = reject;
});
if (copilotCloudPublicApiKey) ctx.properties["copilotCloudPublicApiKey"] = copilotCloudPublicApiKey;
logger.debug("Processing");
let runtimeResponse;
const { eventSource, threadId = (0, _copilotkit_shared.randomId)(), runId, serverSideActions, actionInputsWithoutAgents, extensions } = runtimeResponse;
logger.debug("Event source created, creating response");
const eventStream = eventSource.processRuntimeEvents({
serverSideActions,
guardrailsResult$: data.cloud?.guardrails ? guardrailsResult$ : null,
actionInputsWithoutAgents: actionInputsWithoutAgents.filter((action) => !serverSideActions.find((serverSideAction) => serverSideAction.name == action.name)),
threadId
}).pipe((0, rxjs.shareReplay)(), (0, rxjs.finalize)(() => {
logger.debug("Event stream finalized");
}));
return {
threadId,
runId,
status: (0, rxjs.firstValueFrom)(responseStatus$),
extensions,
metaEvents: new graphql_yoga.Repeater(async (push, stop) => {
let eventStreamSubscription;
eventStreamSubscription = eventStream.subscribe({
next: async (event) => {
if (event.type != require_events.RuntimeEventTypes.MetaEvent) return;
switch (event.name) {
case require_events$1.LangGraphEventTypes.OnInterrupt:
push((0, class_transformer.plainToInstance)(require_meta_events_type.LangGraphInterruptEvent, {
type: event.type,
name: require_events.RuntimeMetaEventName.LangGraphInterruptEvent,
value: event.value
}));
break;
case require_events.RuntimeMetaEventName.LangGraphInterruptEvent:
push((0, class_transformer.plainToInstance)(require_meta_events_type.LangGraphInterruptEvent, {
type: event.type,
name: event.name,
value: event.value
}));
break;
case require_events.RuntimeMetaEventName.CopilotKitLangGraphInterruptEvent:
push((0, class_transformer.plainToInstance)(require_meta_events_type.CopilotKitLangGraphInterruptEvent, {
type: event.type,
name: event.name,
data: {
value: event.data.value,
messages: event.data.messages.map((message) => {
if (message.type === "TextMessage" || "content" in message && "role" in message) return (0, class_transformer.plainToInstance)(require_index.TextMessage, {
id: message.id,
createdAt: /* @__PURE__ */ new Date(),
content: [message.content],
role: message.role,
status: new require_message_status_type.SuccessMessageStatus()
});
if ("arguments" in message) return (0, class_transformer.plainToInstance)(require_index.ActionExecutionMessage, {
name: message.name,
id: message.id,
arguments: [JSON.stringify(message.arguments)],
createdAt: /* @__PURE__ */ new Date(),
status: new require_message_status_type.SuccessMessageStatus()
});
throw new Error("Unknown message in metaEvents copilot resolver");
})
}
}));
break;
}
},
error: (err) => {
if (err?.name?.includes("CopilotKit") || err?.extensions?.visibility) responseStatus$.next(new require_failed_response_status_reasons.UnknownErrorResponse({ description: err.message || "Agent error occurred" }));
else responseStatus$.next(new require_failed_response_status_reasons.UnknownErrorResponse({ description: `An unknown error has occurred in the event stream` }));
eventStreamSubscription?.unsubscribe();
stop();
},
complete: async () => {
logger.debug("Meta events stream completed");
responseStatus$.next(new require_response_status_type.SuccessResponseStatus());
eventStreamSubscription?.unsubscribe();
stop();
}
});
}),
messages: new graphql_yoga.Repeater(async (pushMessage, stopStreamingMessages) => {
logger.debug("Messages repeater created");
if (data.cloud?.guardrails) {
logger = logger.child({ guardrails: true });
logger.debug("Guardrails is enabled, validating input");
invokeGuardrails({
baseUrl: copilotCloudBaseUrl,
copilotCloudPublicApiKey,
data,
onResult: (result) => {
logger.debug({ status: result.status }, "Guardrails validation done");
guardrailsResult$.next(result);
if (result.status === "denied") {
responseStatus$.next(new require_failed_response_status_reasons.GuardrailsValidationFailureResponse({ guardrailsReason: result.reason }));
interruptStreaming$.next({ reason: `Interrupted due to Guardrails validation failure. Reason: ${result.reason}` });
outputMessages = [(0, class_transformer.plainToInstance)(require_index.TextMessage, {
id: (0, _copilotkit_shared.randomId)(),
createdAt: /* @__PURE__ */ new Date(),
content: result.reason,
role: require_enums.MessageRole.assistant
})];
resolveOutputMessagesPromise(outputMessages);
}
},
onError: (err) => {
logger.error({ err }, "Error in guardrails validation");
responseStatus$.next(new require_failed_response_status_reasons.UnknownErrorResponse({ description: `An unknown error has occurred in the guardrails validation` }));
interruptStreaming$.next({ reason: `Interrupted due to unknown error in guardrails validation` });
rejectOutputMessagesPromise(err);
}
});
}
let eventStreamSubscription;
logger.debug("Event stream created, subscribing to event stream");
eventStreamSubscription = eventStream.subscribe({
next: async (event) => {
switch (event.type) {
case require_events.RuntimeEventTypes.MetaEvent: break;
case require_events.RuntimeEventTypes.TextMessageStart:
const textMessageContentStream = eventStream.pipe((0, rxjs.skipWhile)((e) => e !== event), (0, rxjs.takeWhile)((e) => !(e.type === require_events.RuntimeEventTypes.TextMessageEnd && e.messageId == event.messageId)), (0, rxjs.filter)((e) => e.type == require_events.RuntimeEventTypes.TextMessageContent && e.messageId == event.messageId));
const streamingTextStatus = new rxjs.Subject();
const messageId = require_resolve_message_id.resolveMessageId(event.messageId);
pushMessage({
id: messageId,
parentMessageId: event.parentMessageId,
status: (0, rxjs.firstValueFrom)(streamingTextStatus),
createdAt: /* @__PURE__ */ new Date(),
role: require_enums.MessageRole.assistant,
content: new graphql_yoga.Repeater(async (pushTextChunk, stopStreamingText) => {
logger.debug("Text message content repeater created");
const textChunks = [];
let textSubscription;
interruptStreaming$.pipe((0, rxjs.shareReplay)(), (0, rxjs.take)(1), (0, rxjs.tap)(({ reason, messageId }) => {
logger.debug({
reason,
messageId
}, "Text streaming interrupted");
streamingTextStatus.next((0, class_transformer.plainToInstance)(require_message_status_type.FailedMessageStatus, { reason }));
responseStatus$.next(new require_failed_response_status_reasons.MessageStreamInterruptedResponse({ messageId }));
stopStreamingText();
textSubscription?.unsubscribe();
})).subscribe();
logger.debug("Subscribing to text message content stream");
textSubscription = textMessageContentStream.subscribe({
next: async (e) => {
if (e.type == require_events.RuntimeEventTypes.TextMessageContent) {
await pushTextChunk(e.content);
textChunks.push(e.content);
}
},
error: (err) => {
logger.error({ err }, "Error in text message content stream");
interruptStreaming$.next({
reason: "Error streaming message content",
messageId
});
stopStreamingText();
textSubscription?.unsubscribe();
},
complete: () => {
logger.debug("Text message content stream completed");
streamingTextStatus.next(new require_message_status_type.SuccessMessageStatus());
stopStreamingText();
textSubscription?.unsubscribe();
outputMessages.push((0, class_transformer.plainToInstance)(require_index.TextMessage, {
id: messageId,
createdAt: /* @__PURE__ */ new Date(),
content: textChunks.join(""),
role: require_enums.MessageRole.assistant
}));
}
});
})
});
break;
case require_events.RuntimeEventTypes.ActionExecutionStart:
logger.debug("Action execution start event received");
const actionExecutionArgumentStream = eventStream.pipe((0, rxjs.skipWhile)((e) => e !== event), (0, rxjs.takeWhile)((e) => !(e.type === require_events.RuntimeEventTypes.ActionExecutionEnd && e.actionExecutionId == event.actionExecutionId)), (0, rxjs.filter)((e) => e.type == require_events.RuntimeEventTypes.ActionExecutionArgs && e.actionExecutionId == event.actionExecutionId));
const streamingArgumentsStatus = new rxjs.Subject();
pushMessage({
id: event.actionExecutionId,
parentMessageId: event.parentMessageId,
status: (0, rxjs.firstValueFrom)(streamingArgumentsStatus),
createdAt: /* @__PURE__ */ new Date(),
name: event.actionName,
arguments: new graphql_yoga.Repeater(async (pushArgumentsChunk, stopStreamingArguments) => {
logger.debug("Action execution argument stream created");
const argumentChunks = [];
let actionExecutionArgumentSubscription;
actionExecutionArgumentSubscription = actionExecutionArgumentStream.subscribe({
next: async (e) => {
if (e.type == require_events.RuntimeEventTypes.ActionExecutionArgs) {
await pushArgumentsChunk(e.args);
argumentChunks.push(e.args);
}
},
error: (err) => {
logger.error({ err }, "Error in action execution argument stream");
streamingArgumentsStatus.next((0, class_transformer.plainToInstance)(require_message_status_type.FailedMessageStatus, { reason: "An unknown error has occurred in the action execution argument stream" }));
stopStreamingArguments();
actionExecutionArgumentSubscription?.unsubscribe();
},
complete: () => {
logger.debug("Action execution argument stream completed");
streamingArgumentsStatus.next(new require_message_status_type.SuccessMessageStatus());
stopStreamingArguments();
actionExecutionArgumentSubscription?.unsubscribe();
outputMessages.push((0, class_transformer.plainToInstance)(require_index.ActionExecutionMessage, {
id: event.actionExecutionId,
createdAt: /* @__PURE__ */ new Date(),
name: event.actionName,
arguments: argumentChunks.join("")
}));
}
});
})
});
break;
case require_events.RuntimeEventTypes.ActionExecutionResult:
logger.debug({ result: event.result }, "Action execution result event received");
pushMessage({
id: "result-" + event.actionExecutionId,
status: new require_message_status_type.SuccessMessageStatus(),
createdAt: /* @__PURE__ */ new Date(),
actionExecutionId: event.actionExecutionId,
actionName: event.actionName,
result: event.result
});
outputMessages.push((0, class_transformer.plainToInstance)(require_index.ResultMessage, {
id: "result-" + event.actionExecutionId,
createdAt: /* @__PURE__ */ new Date(),
actionExecutionId: event.actionExecutionId,
actionName: event.actionName,
result: event.result
}));
break;
case require_events.RuntimeEventTypes.AgentStateMessage:
logger.debug({ event }, "Agent message event received");
pushMessage({
id: (0, _copilotkit_shared.randomId)(),
status: new require_message_status_type.SuccessMessageStatus(),
threadId: event.threadId,
agentName: event.agentName,
nodeName: event.nodeName,
runId: event.runId,
active: event.active,
state: event.state,
running: event.running,
role: require_enums.MessageRole.assistant,
createdAt: /* @__PURE__ */ new Date()
});
outputMessages.push((0, class_transformer.plainToInstance)(require_index.AgentStateMessage, {
id: (0, _copilotkit_shared.randomId)(),
threadId: event.threadId,
agentName: event.agentName,
nodeName: event.nodeName,
runId: event.runId,
active: event.active,
state: event.state,
running: event.running,
role: require_enums.MessageRole.assistant,
createdAt: /* @__PURE__ */ new Date()
}));
break;
}
},
error: (err) => {
if (err instanceof _copilotkit_shared.CopilotKitError || err instanceof _copilotkit_shared.CopilotKitLowLevelError || err instanceof Error && err.name && err.name.includes("CopilotKit") || err?.extensions?.visibility) {
responseStatus$.next(new require_failed_response_status_reasons.UnknownErrorResponse({
description: err.message || "Agent error occurred",
originalError: {
code: err.code || err.extensions?.code,
statusCode: err.statusCode || err.extensions?.statusCode,
severity: err.severity || err.extensions?.severity,
visibility: err.visibility || err.extensions?.visibility,
originalErrorType: err.originalErrorType || err.extensions?.originalErrorType,
extensions: err.extensions
}
}));
eventStreamSubscription?.unsubscribe();
rejectOutputMessagesPromise(err);
stopStreamingMessages();
return;
}
responseStatus$.next(new require_failed_response_status_reasons.UnknownErrorResponse({ description: `An unknown error has occurred in the event stream` }));
eventStreamSubscription?.unsubscribe();
stopStreamingMessages();
rejectOutputMessagesPromise(err);
},
complete: async () => {
logger.debug("Event stream completed");
if (data.cloud?.guardrails) {
logger.debug("Guardrails is enabled, waiting for guardrails result");
await (0, rxjs.firstValueFrom)(guardrailsResult$);
}
responseStatus$.next(new require_response_status_type.SuccessResponseStatus());
eventStreamSubscription?.unsubscribe();
stopStreamingMessages();
resolveOutputMessagesPromise(outputMessages);
}
});
})
};
}
};
require_decorate.__decorate([
(0, type_graphql.Query)(() => String),
require_decorateMetadata.__decorateMetadata("design:type", Function),
require_decorateMetadata.__decorateMetadata("design:paramtypes", []),
require_decorateMetadata.__decorateMetadata("design:returntype", Promise)
], CopilotResolver.prototype, "hello", null);
require_decorate.__decorate([
(0, type_graphql.Query)(() => require_agents_response_type.AgentsResponse),
require_decorateParam.__decorateParam(0, (0, type_graphql.Ctx)()),
require_decorateMetadata.__decorateMetadata("design:type", Function),
require_decorateMetadata.__decorateMetadata("design:paramtypes", [Object]),
require_decorateMetadata.__decorateMetadata("design:returntype", Promise)
], CopilotResolver.prototype, "availableAgents", null);
require_decorate.__decorate([
(0, type_graphql.Mutation)(() => require_copilot_response_type.CopilotResponse),
require_decorateParam.__decorateParam(0, (0, type_graphql.Ctx)()),
require_decorateParam.__decorateParam(1, (0, type_graphql.Arg)("data")),
require_decorateParam.__decorateParam(2, (0, type_graphql.Arg)("properties", () => graphql_scalars.GraphQLJSONObject, { nullable: true })),
require_decorateMetadata.__decorateMetadata("design:type", Function),
require_decorateMetadata.__decorateMetadata("design:paramtypes", [
Object,
typeof (_ref = typeof require_generate_copilot_response_input.GenerateCopilotResponseInput !== "undefined" && require_generate_copilot_response_input.GenerateCopilotResponseInput) === "function" ? _ref : Object,
Object
]),
require_decorateMetadata.__decorateMetadata("design:returntype", Promise)
], CopilotResolver.prototype, "generateCopilotResponse", null);
CopilotResolver = require_decorate.__decorate([(0, type_graphql.Resolver)(() => require_copilot_response_type.CopilotResponse)], CopilotResolver);
//#endregion
Object.defineProperty(exports, 'CopilotResolver', {
enumerable: true,
get: function () {
return CopilotResolver;
}
});
//# sourceMappingURL=copilot.resolver.cjs.map