@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;" />
85 lines (76 loc) • 2.47 kB
text/typescript
/**
* CopilotKit Adapter for Ollama
*
* <RequestExample>
* ```jsx CopilotRuntime Example
* const copilotKit = new CopilotRuntime();
* return copilotKit.response(req, new OllamaAdapter());
* ```
* </RequestExample>
*
* You can easily set the model to use by passing it to the constructor.
* ```jsx
* const copilotKit = new CopilotRuntime();
* return copilotKit.response(
* req,
* new OllamaAdapter({ model: "llama3-70b-8192" }),
* );
* ```
*/
import { TextMessage } from "../../../graphql/types/converted";
import {
CopilotServiceAdapter,
CopilotRuntimeChatCompletionRequest,
CopilotRuntimeChatCompletionResponse,
} from "../../service-adapter";
import { randomId, randomUUID } from "@copilotkit/shared";
const DEFAULT_MODEL = "llama3:latest";
interface OllamaAdapterOptions {
model?: string;
}
export class ExperimentalOllamaAdapter implements CopilotServiceAdapter {
public model: string;
public provider = "ollama";
public get name() {
return "OllamaAdapter";
}
constructor(options?: OllamaAdapterOptions) {
if (options?.model) {
this.model = options.model;
} else {
this.model = DEFAULT_MODEL;
}
}
async process(
request: CopilotRuntimeChatCompletionRequest,
): Promise<CopilotRuntimeChatCompletionResponse> {
const { messages, actions, eventSource } = request;
// const messages = this.transformMessages(forwardedProps.messages);
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { Ollama } = require("@langchain/community/llms/ollama");
const ollama = new Ollama({
model: this.model,
});
const contents = (messages.filter((m) => m.isTextMessage()) as TextMessage[]).map(
(m) => m.content,
);
const _stream = await ollama.stream(contents); // [TODO] role info is dropped...
eventSource.stream(async (eventStream$) => {
const currentMessageId = randomId();
eventStream$.sendTextMessageStart({ messageId: currentMessageId });
for await (const chunkText of _stream) {
eventStream$.sendTextMessageContent({
messageId: currentMessageId,
content: chunkText,
});
}
eventStream$.sendTextMessageEnd({ messageId: currentMessageId });
// we may need to add this later.. [nc]
// let calls = (await result.response).functionCalls();
eventStream$.complete();
});
return {
threadId: request.threadId || randomUUID(),
};
}
}