1
0

ollamaChat.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import { ChatbotBackend, VisionBackend } from "@/types/backend";
  2. import { Message } from "./messages";
  3. export async function getOllamaChatResponseStream(config: ChatbotBackend["ollama"],messages: Message[]) {
  4. const headers: Record<string, string> = {
  5. "Content-Type": "application/json",
  6. };
  7. const res = await fetch(`${config?.ollama_url}/api/chat`, {
  8. headers: headers,
  9. method: "POST",
  10. body: JSON.stringify({
  11. model: config?.ollama_model,
  12. messages,
  13. }),
  14. });
  15. const reader = res.body?.getReader();
  16. if (res.status !== 200 || ! reader) {
  17. throw new Error(`Ollama chat error (${res.status})`);
  18. }
  19. const stream = new ReadableStream({
  20. async start(controller: ReadableStreamDefaultController) {
  21. const decoder = new TextDecoder("utf-8");
  22. try {
  23. // Ollama sends chunks of multiple complete JSON objects separated by newlines
  24. while (true) {
  25. const { done, value } = await reader.read();
  26. if (done) break;
  27. const data = decoder.decode(value);
  28. const jsonResponses = data
  29. .trim() // Ollama sends an empty line after the final JSON message...
  30. .split("\n")
  31. //.filter((val) => !!val)
  32. for (const jsonResponse of jsonResponses) {
  33. try {
  34. const json = JSON.parse(jsonResponse);
  35. const messagePiece = json.message.content;
  36. if (!!messagePiece) {
  37. controller.enqueue(messagePiece);
  38. }
  39. } catch (error) {
  40. console.error(error);
  41. }
  42. }
  43. }
  44. } catch (error) {
  45. console.error(error);
  46. controller.error(error);
  47. } finally {
  48. reader.releaseLock();
  49. controller.close();
  50. }
  51. },
  52. async cancel() {
  53. await reader?.cancel();
  54. reader.releaseLock();
  55. }
  56. });
  57. return stream;
  58. }
  59. export async function getOllamaVisionChatResponse(config: VisionBackend["vision_ollama"],messages: Message[], imageData: string) {
  60. const headers: Record<string, string> = {
  61. "Content-Type": "application/json",
  62. };
  63. const res = await fetch(`${config?.vision_ollama_url}/api/chat`, {
  64. headers: headers,
  65. method: "POST",
  66. body: JSON.stringify({
  67. model: config?.vision_ollama_model,
  68. messages,
  69. images: [imageData],
  70. stream: false,
  71. }),
  72. });
  73. if (res.status !== 200) {
  74. throw new Error(`Ollama chat error (${res.status})`);
  75. }
  76. const json = await res.json();
  77. return json.response;
  78. }