Comparing version
@@ -1,2 +0,2 @@ | ||
import type { Config, Tag, GenerateResult, CreateStatus, PullResult } from "./interfaces.js"; | ||
import type { Config, Tag, GenerateResult, CreateStatus, PullResult, GenerateOptions, ModelParameters } from "./interfaces.js"; | ||
export declare class Ollama { | ||
@@ -6,3 +6,3 @@ private readonly config; | ||
tags(): Promise<Tag[]>; | ||
generate(model: string, prompt: string): AsyncGenerator<string, GenerateResult>; | ||
generate(model: string, prompt: string, options?: Partial<GenerateOptions>): AsyncGenerator<string, GenerateResult>; | ||
create(name: string, path: string): AsyncGenerator<CreateStatus>; | ||
@@ -12,4 +12,4 @@ copy(source: string, destination: string): Promise<void>; | ||
pull(name: string): AsyncGenerator<PullResult>; | ||
embeddings(model: string, prompt: string): Promise<number[]>; | ||
embeddings(model: string, prompt: string, parameters?: Partial<ModelParameters>): Promise<number[]>; | ||
} | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,189 +0,99 @@ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } | ||
var __asyncValues = (this && this.__asyncValues) || function (o) { | ||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); | ||
var m = o[Symbol.asyncIterator], i; | ||
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i); | ||
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; } | ||
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); } | ||
}; | ||
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { | ||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); | ||
var g = generator.apply(thisArg, _arguments || []), i, q = []; | ||
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; | ||
function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } | ||
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } | ||
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } | ||
function fulfill(value) { resume("next", value); } | ||
function reject(value) { resume("throw", value); } | ||
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } | ||
}; | ||
import * as utils from "./utils.js"; | ||
export class Ollama { | ||
config; | ||
constructor(config) { | ||
var _a; | ||
this.config = { | ||
address: (_a = config === null || config === void 0 ? void 0 : config.address) !== null && _a !== void 0 ? _a : "http://localhost:11434" | ||
address: config?.address ?? "http://localhost:11434" | ||
}; | ||
} | ||
tags() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const response = yield utils.get(`${this.config.address}/api/tags`); | ||
const json = yield response.json(); | ||
return json.models.map(m => ({ | ||
name: m.name, | ||
modifiedAt: new Date(m.modified_at), | ||
size: m.size | ||
})); | ||
}); | ||
async tags() { | ||
const response = await utils.get(`${this.config.address}/api/tags`); | ||
const json = await response.json(); | ||
return json.models.map(m => ({ | ||
name: m.name, | ||
modifiedAt: new Date(m.modified_at), | ||
size: m.size | ||
})); | ||
} | ||
generate(model, prompt) { | ||
return __asyncGenerator(this, arguments, function* generate_1() { | ||
var _a, e_1, _b, _c; | ||
const response = yield __await(utils.post(`${this.config.address}/api/generate`, { model, prompt })); | ||
if (!response.body) { | ||
throw new Error("Missing body"); | ||
} | ||
try { | ||
for (var _d = true, _e = __asyncValues(response.body), _f; _f = yield __await(_e.next()), _a = _f.done, !_a;) { | ||
_c = _f.value; | ||
_d = false; | ||
try { | ||
const chunk = _c; | ||
const messages = chunk.toString().split("\n").filter(s => s.length !== 0); | ||
for (const message of messages) { | ||
const res = JSON.parse(message); | ||
if (res.done) { | ||
return yield __await({ | ||
model: res.model, | ||
createdAt: new Date(res.created_at), | ||
context: res.context, | ||
totalDuration: res.total_duration, | ||
loadDuration: res.load_duration, | ||
promptEvalCount: res.prompt_eval_count, | ||
evalCount: res.eval_count, | ||
evalDuration: res.eval_duration | ||
}); | ||
} | ||
yield yield __await(res.response); | ||
} | ||
} | ||
finally { | ||
_d = true; | ||
} | ||
async *generate(model, prompt, options) { | ||
const parameters = options?.parameters; | ||
delete options?.parameters; | ||
const request = { model, prompt, ...options }; | ||
if (parameters != null) { | ||
request.options = parameters; | ||
} | ||
const response = await utils.post(`${this.config.address}/api/generate`, { ...request }); | ||
if (!response.body) { | ||
throw new Error("Missing body"); | ||
} | ||
for await (const chunk of response.body) { | ||
const messages = chunk.toString().split("\n").filter(s => s.length !== 0); | ||
for (const message of messages) { | ||
const res = JSON.parse(message); | ||
if (res.done) { | ||
return { | ||
model: res.model, | ||
createdAt: new Date(res.created_at), | ||
context: res.context, | ||
totalDuration: res.total_duration, | ||
loadDuration: res.load_duration, | ||
promptEvalCount: res.prompt_eval_count, | ||
evalCount: res.eval_count, | ||
evalDuration: res.eval_duration | ||
}; | ||
} | ||
yield res.response; | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e)); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
throw new Error("Did not recieve done response in stream."); | ||
}); | ||
} | ||
throw new Error("Did not recieve done response in stream."); | ||
} | ||
create(name, path) { | ||
return __asyncGenerator(this, arguments, function* create_1() { | ||
var _a, e_2, _b, _c; | ||
const response = yield __await(utils.post(`${this.config.address}/api/create`, { name, path })); | ||
if (!response.body) { | ||
throw new Error("Missing body"); | ||
async *create(name, path) { | ||
const response = await utils.post(`${this.config.address}/api/create`, { name, path }); | ||
if (!response.body) { | ||
throw new Error("Missing body"); | ||
} | ||
for await (const chunk of response.body) { | ||
const messages = chunk.toString().split("\n").filter(s => s.length !== 0); | ||
for (const message of messages) { | ||
const res = JSON.parse(message); | ||
yield res.status; | ||
} | ||
try { | ||
for (var _d = true, _e = __asyncValues(response.body), _f; _f = yield __await(_e.next()), _a = _f.done, !_a;) { | ||
_c = _f.value; | ||
_d = false; | ||
try { | ||
const chunk = _c; | ||
const messages = chunk.toString().split("\n").filter(s => s.length !== 0); | ||
for (const message of messages) { | ||
const res = JSON.parse(message); | ||
yield yield __await(res.status); | ||
} | ||
} | ||
finally { | ||
_d = true; | ||
} | ||
} | ||
} | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
finally { | ||
try { | ||
if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e)); | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
} | ||
}); | ||
} | ||
} | ||
copy(source, destination) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield utils.post(`${this.config.address}/api/copy`, { | ||
source, | ||
destination | ||
}); | ||
async copy(source, destination) { | ||
await utils.post(`${this.config.address}/api/copy`, { | ||
source, | ||
destination | ||
}); | ||
} | ||
delete(name) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield utils.del(`${this.config.address}/api/delete`, { name }); | ||
}); | ||
async delete(name) { | ||
await utils.del(`${this.config.address}/api/delete`, { name }); | ||
} | ||
pull(name) { | ||
var _a, _b, _c; | ||
return __asyncGenerator(this, arguments, function* pull_1() { | ||
var _d, e_3, _e, _f; | ||
const response = yield __await(utils.post(`${this.config.address}/api/pull`, { name })); | ||
if (!response.body) { | ||
throw new Error("Missing body"); | ||
async *pull(name) { | ||
const response = await utils.post(`${this.config.address}/api/pull`, { name }); | ||
if (!response.body) { | ||
throw new Error("Missing body"); | ||
} | ||
for await (const chunk of response.body) { | ||
const messages = chunk.toString().split("\n").filter(s => s.length !== 0); | ||
for (const message of messages) { | ||
const res = JSON.parse(message); | ||
yield { | ||
status: res.status, | ||
digest: res["digest"] ?? "", | ||
total: res["total"] ?? 0, | ||
completed: res["completed"] ?? 0 | ||
}; | ||
} | ||
try { | ||
for (var _g = true, _h = __asyncValues(response.body), _j; _j = yield __await(_h.next()), _d = _j.done, !_d;) { | ||
_f = _j.value; | ||
_g = false; | ||
try { | ||
const chunk = _f; | ||
const messages = chunk.toString().split("\n").filter(s => s.length !== 0); | ||
for (const message of messages) { | ||
const res = JSON.parse(message); | ||
yield yield __await({ | ||
status: res.status, | ||
digest: (_a = res["digest"]) !== null && _a !== void 0 ? _a : "", | ||
total: (_b = res["total"]) !== null && _b !== void 0 ? _b : 0, | ||
completed: (_c = res["completed"]) !== null && _c !== void 0 ? _c : 0 | ||
}); | ||
} | ||
} | ||
finally { | ||
_g = true; | ||
} | ||
} | ||
} | ||
catch (e_3_1) { e_3 = { error: e_3_1 }; } | ||
finally { | ||
try { | ||
if (!_g && !_d && (_e = _h.return)) yield __await(_e.call(_h)); | ||
} | ||
finally { if (e_3) throw e_3.error; } | ||
} | ||
}); | ||
} | ||
} | ||
embeddings(model, prompt) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const response = yield utils.post(`${this.config.address}/api/embeddings`, { | ||
model, | ||
prompt | ||
}); | ||
const json = yield response.json(); | ||
return json.embedding; | ||
async embeddings(model, prompt, parameters) { | ||
const response = await utils.post(`${this.config.address}/api/embeddings`, { | ||
model, | ||
prompt, | ||
options: parameters ?? {} | ||
}); | ||
const json = await response.json(); | ||
return json.embedding; | ||
} | ||
} |
export interface Config { | ||
address: string; | ||
} | ||
export interface ModelParameters { | ||
mirostat: number; | ||
mirostat_eta: number; | ||
mirostat_tau: number; | ||
num_ctx: number; | ||
num_gqa: number; | ||
num_thread: number; | ||
repeat_last_n: number; | ||
repeat_penalty: number; | ||
temperature: number; | ||
stop: string; | ||
tfs_z: number; | ||
top_k: number; | ||
top_p: number; | ||
} | ||
export interface GenerateOptions { | ||
parameters: Partial<ModelParameters>; | ||
context: number[]; | ||
template: string; | ||
system: string; | ||
} | ||
export interface GenerateResult { | ||
@@ -35,2 +56,10 @@ model: string; | ||
} | ||
export interface GenerateRequest { | ||
model: string; | ||
prompt: string; | ||
options?: Partial<ModelParameters>; | ||
system?: string; | ||
template?: string; | ||
context?: number[]; | ||
} | ||
export interface GenerateResponse { | ||
@@ -37,0 +66,0 @@ model: string; |
@@ -1,10 +0,1 @@ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
import fetch from "node-fetch"; | ||
@@ -20,5 +11,5 @@ export const formatAddress = (address) => { | ||
}; | ||
const checkOk = (response) => __awaiter(void 0, void 0, void 0, function* () { | ||
const checkOk = async (response) => { | ||
if (!response.ok) { | ||
let message = yield response.text(); | ||
let message = await response.text(); | ||
try { | ||
@@ -32,23 +23,23 @@ message = JSON.parse(message).error; | ||
} | ||
}); | ||
export const get = (address) => __awaiter(void 0, void 0, void 0, function* () { | ||
const response = yield fetch(formatAddress(address)); | ||
yield checkOk(response); | ||
}; | ||
export const get = async (address) => { | ||
const response = await fetch(formatAddress(address)); | ||
await checkOk(response); | ||
return response; | ||
}); | ||
export const post = (address, data) => __awaiter(void 0, void 0, void 0, function* () { | ||
const response = yield fetch(formatAddress(address), { | ||
}; | ||
export const post = async (address, data) => { | ||
const response = await fetch(formatAddress(address), { | ||
method: "POST", | ||
body: JSON.stringify(data) | ||
}); | ||
yield checkOk(response); | ||
await checkOk(response); | ||
return response; | ||
}); | ||
export const del = (address, data) => __awaiter(void 0, void 0, void 0, function* () { | ||
const response = yield fetch(formatAddress(address), { | ||
}; | ||
export const del = async (address, data) => { | ||
const response = await fetch(formatAddress(address), { | ||
method: "DELETE", | ||
body: JSON.stringify(data) | ||
}); | ||
yield checkOk(response); | ||
await checkOk(response); | ||
return response; | ||
}); | ||
}; |
{ | ||
"type": "module", | ||
"name": "ollama", | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"description": "Interface with an ollama instance over HTTP.", | ||
@@ -6,0 +6,0 @@ "main": "dist/index.js", |
@@ -56,3 +56,3 @@ # ollama | ||
```javascript | ||
ollama.generate(model, prompt); | ||
ollama.generate(model, prompt, [options]); | ||
``` | ||
@@ -62,2 +62,7 @@ | ||
- `prompt` `<string>` The prompt to give the model. | ||
- `options` `<GenerateOptions>` Optional options to pass to the model. | ||
- `parameters` `<ModelParameters>` Model Parameters. | ||
- `context` `<number[]>` Context returned from previous calls. | ||
- `template` `<string>` Override the default template. | ||
- `system` `<string>` Override the default system string. | ||
- Returns: `<AsyncGenerator<string, GenerateResult>>` A generator that outputs the tokens as strings. | ||
@@ -126,3 +131,3 @@ | ||
```javascript | ||
ollama.embeddings(model, prompt); | ||
ollama.embeddings(model, prompt, [parameters]); | ||
``` | ||
@@ -132,2 +137,3 @@ | ||
- `prompt` `<string>` The prompt to generate embeddings with. | ||
- `parameters` `<ModelParameters>` Model Parameters. | ||
- Returns: `Promise<number[]>` The embeddings. | ||
@@ -134,0 +140,0 @@ |
@@ -14,3 +14,6 @@ import * as utils from "./utils.js"; | ||
PullResult, | ||
EmbeddingsResponse | ||
EmbeddingsResponse, | ||
GenerateOptions, | ||
GenerateRequest, | ||
ModelParameters | ||
} from "./interfaces.js"; | ||
@@ -38,5 +41,15 @@ | ||
async * generate (model: string, prompt: string): AsyncGenerator<string, GenerateResult> { | ||
const response = await utils.post(`${this.config.address}/api/generate`, { model, prompt }); | ||
async * generate (model: string, prompt: string, options?: Partial<GenerateOptions>): AsyncGenerator<string, GenerateResult> { | ||
const parameters = options?.parameters; | ||
delete options?.parameters; | ||
const request: GenerateRequest = { model, prompt, ...options }; | ||
if (parameters != null) { | ||
request.options = parameters; | ||
} | ||
const response = await utils.post(`${this.config.address}/api/generate`, { ...request }); | ||
if (!response.body) { | ||
@@ -124,6 +137,7 @@ throw new Error("Missing body"); | ||
async embeddings (model: string, prompt: string): Promise<number[]> { | ||
async embeddings (model: string, prompt: string, parameters?: Partial<ModelParameters>): Promise<number[]> { | ||
const response = await utils.post(`${this.config.address}/api/embeddings`, { | ||
model, | ||
prompt | ||
prompt, | ||
options: parameters ?? {} | ||
}); | ||
@@ -130,0 +144,0 @@ |
@@ -5,2 +5,25 @@ export interface Config { | ||
export interface ModelParameters { | ||
mirostat: number | ||
mirostat_eta: number | ||
mirostat_tau: number | ||
num_ctx: number | ||
num_gqa: number | ||
num_thread: number | ||
repeat_last_n: number | ||
repeat_penalty: number | ||
temperature: number | ||
stop: string | ||
tfs_z: number | ||
top_k: number | ||
top_p: number | ||
} | ||
export interface GenerateOptions { | ||
parameters: Partial<ModelParameters> | ||
context: number[] | ||
template: string | ||
system: string | ||
} | ||
export interface GenerateResult { | ||
@@ -43,2 +66,11 @@ model: string | ||
export interface GenerateRequest { | ||
model: string | ||
prompt: string | ||
options?: Partial<ModelParameters> | ||
system?: string | ||
template?: string | ||
context?: number[] | ||
} | ||
export interface GenerateResponse { | ||
@@ -45,0 +77,0 @@ model: string |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
154
4.05%59706
-5.41%523
-5.6%