diff --git a/examples/example.nim b/examples/example.nim deleted file mode 100644 index 0262224..0000000 --- a/examples/example.nim +++ /dev/null @@ -1 +0,0 @@ -## Include an example on how to use your library diff --git a/src/llama_leap.nim b/src/llama_leap.nim index f5ad29e..b2c2d44 100644 --- a/src/llama_leap.nim +++ b/src/llama_leap.nim @@ -92,6 +92,11 @@ type details*: ModelDetails ListResp* = ref object models*: seq[OllamaModel] + ShowModel* = ref object + modelfile*: string + parameters*: string + template_str*: string + details*: ModelDetails EmbeddingReq* = ref object model*: string prompt*: string @@ -99,24 +104,32 @@ type EmbeddingResp* = ref object embedding*: seq[float64] -proc renameHook*(v: var ChatReq, fieldName: var string) = +proc renameHook(v: var ChatReq, fieldName: var string) = + ## `template` is a special keyword in nim, so we need to rename it during serialization + if fieldName == "template": + fieldName = "template_str" +proc dumpHook(v: var ChatReq, fieldName: var string) = + if fieldName == "template_str": + fieldName = "template" + +proc renameHook(v: var GenerateReq, fieldName: var string) = ## `template` is a special keyword in nim, so we need to rename it during serialization if fieldName == "template": fieldName = "template_str" -proc dumpHook*(v: var ChatReq, fieldName: var string) = +proc dumpHook(v: var GenerateReq, fieldName: var string) = if fieldName == "template_str": fieldName = "template" -proc renameHook*(v: var GenerateReq, fieldName: var string) = +proc renameHook(v: var ShowModel, fieldName: var string) = ## `template` is a special keyword in nim, so we need to rename it during serialization if fieldName == "template": fieldName = "template_str" -proc dumpHook*(v: var GenerateReq, fieldName: var string) = +proc dumpHook(v: var ShowModel, fieldName: var string) = if fieldName == "template_str": fieldName = "template" -proc dumpHook*(s: var string, v: object) = +proc dumpHook(s: var string, v: object) = ## jsony `hack` to skip optional fields that are nil s.add '{' var i = 0 @@ -172,6 +185,7 @@ proc generate*(api: OllamaAPI, req: GenerateReq): GenerateResp = var headers: curly.HttpHeaders headers["Content-Type"] = "application/json" req.stream = option(false) + echo toJson(req) let resp = api.curlPool.post(url, headers, toJson(req), api.curlTimeout) if resp.code != 200: raise newException(CatchableError, &"ollama generate failed: {resp.code} {resp.body}") @@ -267,6 +281,19 @@ proc listModels*(api: OllamaAPI): ListResp = raise newException(CatchableError, &"ollama list tags failed: {resp.code} {resp.body}") result = fromJson(resp.body, ListResp) +proc showModel*(api: OllamaAPI, name: string): ShowModel = + ## get details for a specific model + let url = api.baseUrl / "show" + let req = %*{"name": name} + + var headers: curly.HttpHeaders + headers["Content-Type"] = "application/json" + + let resp = api.curlPool.post(url, headers, toJson(req), api.curlTimeout) + if resp.code != 200: + raise newException(CatchableError, &"ollama show failed: {resp.code} {resp.body}") + result = fromJson(resp.body, ShowModel) + proc pullModel*(api: OllamaAPI, name: string) = ## Ask the ollama server to pull a model let url = api.baseUrl / "pull" @@ -317,3 +344,9 @@ proc generateEmbeddings*( result = fromJson(resp.body, EmbeddingResp) else: result = fromJson(resp.body, EmbeddingResp) + +# TODO: HEAD /api/blobs/:digest +# TODO: POST /api/blobs/:digest +# TODO: POST /api/copy +# TODO: DELETE /api/delete +# TODO: POST /api/push diff --git a/tests/test_llama_leap.nim b/tests/test_llama_leap.nim index 9d81ad8..c16f47b 100644 --- a/tests/test_llama_leap.nim +++ b/tests/test_llama_leap.nim @@ -1,9 +1,11 @@ ## llama_leap API tests ## Ensure that ollama is running! -import llama_leap, std/[unittest, json, options, strutils] +import llama_leap, jsony, std/[unittest, json, options, strutils] -const TestModel = "llama2" +const + TestModel = "llama2" + TestModelfileName = "test-pirate-llama2" suite "llama_leap": var ollama: OllamaAPI @@ -113,7 +115,6 @@ suite "llama_leap": let resp = ollama.chat(req) echo "> " & resp.message.content.strip() suite "create": - let testModelName = "test-pirate-llama2" test "create specifying modelfile": let modelfile = """ FROM llama2 @@ -122,9 +123,16 @@ PARAMETER num_ctx 4096 SYSTEM Please talk like a pirate. You are Longbeard the llama. """ - ollama.createModel(testModelName, modelfile) + ollama.createModel(TestModelfileName, modelfile) test "use our created modelfile": - echo "> " & ollama.generate(testModelName, "How are you today?") + echo "> " & ollama.generate(TestModelfileName, "How are you today?") + + suite "show": + test "show model": + let resp = ollama.showModel(TestModelfileName) + echo "> " & toJson(resp) + # validate that renameHook() is working properly + assert resp.template_str != "" suite "embeddings": test "generate embeddings":