From 14be818716f20ad5c52bc76e88b16b0be8f7e2ab Mon Sep 17 00:00:00 2001 From: kyoh86 Date: Wed, 10 Jan 2024 02:08:08 +0900 Subject: [PATCH] wip: fix generate_completion params --- denops/ollama/api/generate_completion.ts | 53 +++++++++---------- denops/ollama/api/generate_completion_test.ts | 15 +++--- denops/ollama/dispatch/start_chat.ts | 2 +- 3 files changed, 32 insertions(+), 38 deletions(-) diff --git a/denops/ollama/api/generate_completion.ts b/denops/ollama/api/generate_completion.ts index 8abf155..04b7a3a 100644 --- a/denops/ollama/api/generate_completion.ts +++ b/denops/ollama/api/generate_completion.ts @@ -2,7 +2,7 @@ import { is, type PredicateType, } from "https://deno.land/x/unknownutil@v3.13.0/mod.ts"; -import { isErrorResponse, isFormat, type RequestOptions } from "./types.ts"; +import { isErrorResponse, type RequestOptions } from "./types.ts"; import { parseJSONStream } from "./base.ts"; import { doPost } from "./base.ts"; @@ -11,32 +11,6 @@ import { doPost } from "./base.ts"; // Endpoint: /api/generate // Usage: https://github.com/jmorganca/ollama/blob/main/docs/api.md#generate-a-completion -export const isGenerateCompletionParam = is.ObjectOf({ - // The model name - model: is.String, - // The prompt to generate a response for - prompt: is.String, - // (optional) A list of base64-encoded images (for multimodal models such as llava) - images: is.OptionalOf(is.ArrayOf(is.String)), - // (optional) The format to return a response in. Currently the only accepted value is json - format: isFormat, - // (optional) Additional model parameters listed in the documentation for the Modelfile such as temperature - options: is.OptionalOf(is.Record), - // (optional) System message to (overrides what is defined in the Modelfile) - system: is.OptionalOf(is.String), - // (optional) The full prompt or prompt template (overrides what is defined in the Modelfile) - template: is.OptionalOf(is.String), - // (optional) The context parameter returned from a previous request to /generate, this can be used to keep a short conversational memory - context: is.OptionalOf(is.ArrayOf(is.Number)), - // (optional) If false the response will be returned as a single response object, rather than a stream of objects - stream: is.OptionalOf(is.Boolean), - // (optional) If true no formatting will be applied to the prompt. You may choose to use the raw parameter if you are specifying a full templated prompt in your request to the API. - raw: is.OptionalOf(is.Boolean), -}); -export type GenerateCompletionParam = PredicateType< - typeof isGenerateCompletionParam ->; - export const isGenerateCompletionResponse = is.OneOf([ isErrorResponse, is.ObjectOf({ @@ -68,16 +42,37 @@ export type GenerateCompletionResponse = PredicateType< typeof isGenerateCompletionResponse >; +export type GenerateCompletionParam = { + // A list of base64-encoded images (for multimodal models such as llava) + images?: string[] | undefined; + // The format to return a response in. Currently the only accepted value is json + format?: "json" | undefined; + // Additional model parameters listed in the documentation for the Modelfile such as temperature + options?: Record | undefined; + // System message to (overrides what is defined in the Modelfile) + system?: string | undefined; + // The full prompt or prompt template (overrides what is defined in the Modelfile) + template?: string | undefined; + // The context parameter returned from a previous request to /generate, this can be used to keep a short conversational memory + context?: number[] | undefined; + // If true no formatting will be applied to the prompt. You may choose to use the raw parameter if you are specifying a full templated prompt in your request to the API. + raw?: boolean | undefined; +}; + /** Generate a response for a given prompt with a provided model. * This is a streaming endpoint, so there will be a series of responses. * The final response object will include statistics and additional data from the request. */ export async function generateCompletion( - param: GenerateCompletionParam, + // The model name + model: string, + // The prompt to generate a response for + prompt: string, + param?: GenerateCompletionParam, options?: RequestOptions, ) { return parseJSONStream( - await doPost("/api/generate", param, options), + await doPost("/api/generate", { model, prompt, ...param }, options), isGenerateCompletionResponse, ); } diff --git a/denops/ollama/api/generate_completion_test.ts b/denops/ollama/api/generate_completion_test.ts index e64c290..c8ef23b 100644 --- a/denops/ollama/api/generate_completion_test.ts +++ b/denops/ollama/api/generate_completion_test.ts @@ -23,10 +23,10 @@ Deno.test("generateCompletion", async (t) => { }); try { await t.step("should call fetch with the correct arguments", async () => { - const result = await generateCompletion({ - model: "model1", - prompt: "How to run?", - }); + const result = await generateCompletion( + "model1", + "How to run?", + ); assertEquals(result.response.status, 200); assertSpyCalls(fetchStub, 1); assertSpyCallArgs(fetchStub, 0, [ @@ -76,14 +76,13 @@ Deno.test("generateCompletion", async (t) => { try { await t.step("should call fetch with the correct arguments", async () => { const result = await generateCompletion( + "model1", + "run", { - model: "model1", - prompt: "run", context: [1, 2, 3], format: "json", images: ["foo-image-1", "foo-image-2"], system: "foo-system", - stream: true, raw: true, template: "How to %s?", }, @@ -97,7 +96,7 @@ Deno.test("generateCompletion", async (t) => { new URL("https://example.com:33562/api/generate"), { body: - '{"model":"model1","prompt":"run","context":[1,2,3],"format":"json","images":["foo-image-1","foo-image-2"],"system":"foo-system","stream":true,"raw":true,"template":"How to %s?"}', + '{"model":"model1","prompt":"run","context":[1,2,3],"format":"json","images":["foo-image-1","foo-image-2"],"system":"foo-system","raw":true,"template":"How to %s?"}', headers: { "Content-Type": "application/json" }, method: "POST", }, diff --git a/denops/ollama/dispatch/start_chat.ts b/denops/ollama/dispatch/start_chat.ts index 1a6b312..51d9cbf 100644 --- a/denops/ollama/dispatch/start_chat.ts +++ b/denops/ollama/dispatch/start_chat.ts @@ -96,7 +96,7 @@ async function promptCallback( const { signal, cancel } = await canceller(denops); try { - const result = await generateCompletion({ model, prompt, context }, { + const result = await generateCompletion(model, prompt, { context }, { signal, }); if (!result.body) {