Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 55 additions & 2 deletions core/llm/llms/Ollama.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,18 @@ type OllamaErrorResponse = {
error: string;
};

type N8nChatReponse = {
type: string;
content?: string;
metadata: {
nodeId: string;
nodeName: string;
itemIndex: number;
runIndex: number;
timestamps: number;
};
};

type OllamaRawResponse =
| OllamaErrorResponse
| (OllamaBaseResponse & {
Expand All @@ -124,7 +136,8 @@ type OllamaChatResponse =
| OllamaErrorResponse
| (OllamaBaseResponse & {
message: OllamaChatMessage;
});
})
| N8nChatReponse;

interface OllamaTool {
type: "function";
Expand Down Expand Up @@ -427,12 +440,52 @@ class Ollama extends BaseLLM implements ModelInstaller {
body: JSON.stringify(chatOptions),
signal,
});

let _isThinking: boolean = false;
function GetIsThinking(): boolean {
return _isThinking;
}
function SetIsThinking(newValue: boolean): void {
if (_isThinking !== newValue) {
_isThinking = newValue;
}
}
function convertChatMessage(res: OllamaChatResponse): ChatMessage[] {
if ("error" in res) {
throw new Error(res.error);
}

if ("type" in res) {
const { content } = res;

if (content === "<think>") {
SetIsThinking(true);
}

if (GetIsThinking() && content) {
const thinkingMessage: ThinkingChatMessage = {
role: "thinking",
content: content,
};

if (thinkingMessage) {
if (content === "</think>") {
SetIsThinking(false);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note we generally use camelcase for methods

}
// When Streaming you can't have both thinking and content
return [thinkingMessage];
}
}

if (content) {
const chatMessage: ChatMessage = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other thoughts:
Could n8n have tool calls at all or not really?
Could we detect thinking from e.g. type field? On first look I wasn't able to pinpoint where docs for the N8nChatReponse would be, could you link them?

role: "assistant",
content: content,
};
return [chatMessage];
}
return [];
}

const { role, content, thinking, tool_calls: toolCalls } = res.message;

if (role === "tool") {
Expand Down
Loading