Skip to content

Commit

Permalink
update config address to host
Browse files Browse the repository at this point in the history
  • Loading branch information
BruceMacD authored Jan 22, 2024
2 parents 9f60d79 + 7f2415f commit 097fdf3
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 40 deletions.
30 changes: 13 additions & 17 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class Ollama {

constructor(config?: Partial<Config>) {
this.config = {
address: config?.address ?? 'http://127.0.0.1:11434',
host: utils.formatHost(config?.host ?? 'http://127.0.0.1:11434'),
}

this.fetch = fetch
Expand All @@ -47,11 +47,9 @@ export class Ollama {
request: { stream?: boolean } & Record<string, any>,
): Promise<T | AsyncGenerator<T>> {
request.stream = request.stream ?? false
const response = await utils.post(
this.fetch,
`${this.config.address}/api/${endpoint}`,
{ ...request },
)
const response = await utils.post(this.fetch, `${this.config.host}/api/${endpoint}`, {
...request,
})

if (!response.body) {
throw new Error('Missing body')
Expand Down Expand Up @@ -158,7 +156,7 @@ export class Ollama {
const digest = `sha256:${sha256sum}`

try {
await utils.head(this.fetch, `${this.config.address}/api/blobs/${digest}`)
await utils.head(this.fetch, `${this.config.host}/api/blobs/${digest}`)
} catch (e) {
if (e instanceof Error && e.message.includes('404')) {
// Create a new readable stream for the fetch request
Expand All @@ -180,7 +178,7 @@ export class Ollama {

await utils.post(
this.fetch,
`${this.config.address}/api/blobs/${digest}`,
`${this.config.host}/api/blobs/${digest}`,
readableStream,
)
} else {
Expand Down Expand Up @@ -280,37 +278,35 @@ export class Ollama {
}

async delete(request: DeleteRequest): Promise<StatusResponse> {
await utils.del(this.fetch, `${this.config.address}/api/delete`, {
await utils.del(this.fetch, `${this.config.host}/api/delete`, {
name: request.model,
})
return { status: 'success' }
}

async copy(request: CopyRequest): Promise<StatusResponse> {
await utils.post(this.fetch, `${this.config.address}/api/copy`, { ...request })
await utils.post(this.fetch, `${this.config.host}/api/copy`, { ...request })
return { status: 'success' }
}

async list(): Promise<ListResponse> {
const response = await utils.get(this.fetch, `${this.config.address}/api/tags`)
const response = await utils.get(this.fetch, `${this.config.host}/api/tags`)
const listResponse = (await response.json()) as ListResponse
return listResponse
}

async show(request: ShowRequest): Promise<ShowResponse> {
const response = await utils.post(this.fetch, `${this.config.address}/api/show`, {
const response = await utils.post(this.fetch, `${this.config.host}/api/show`, {
...request,
})
const showResponse = (await response.json()) as ShowResponse
return showResponse
}

async embeddings(request: EmbeddingsRequest): Promise<EmbeddingsResponse> {
const response = await utils.post(
this.fetch,
`${this.config.address}/api/embeddings`,
{ request },
)
const response = await utils.post(this.fetch, `${this.config.host}/api/embeddings`, {
request,
})
const embeddingsResponse = (await response.json()) as EmbeddingsResponse
return embeddingsResponse
}
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export type Fetch = typeof fetch

export interface Config {
address: string
host: string
fetch?: Fetch
}

Expand Down
66 changes: 46 additions & 20 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
import type { Fetch, ErrorResponse } from './interfaces.js'

export const formatAddress = (address: string): string => {
if (!address.startsWith('http://') && !address.startsWith('https://')) {
address = `http://${address}`
}

while (address.endsWith('/')) {
address = address.substring(0, address.length - 1)
}

return address
}

const checkOk = async (response: Response): Promise<void> => {
if (!response.ok) {
let message = `Error ${response.status}: ${response.statusText}`
Expand All @@ -38,16 +26,16 @@ const checkOk = async (response: Response): Promise<void> => {
}
}

export const get = async (fetch: Fetch, address: string): Promise<Response> => {
const response = await fetch(formatAddress(address))
export const get = async (fetch: Fetch, host: string): Promise<Response> => {
const response = await fetch(host)

await checkOk(response)

return response
}

export const head = async (fetch: Fetch, address: string): Promise<Response> => {
const response = await fetch(formatAddress(address), {
export const head = async (fetch: Fetch, host: string): Promise<Response> => {
const response = await fetch(host, {
method: 'HEAD',
})

Expand All @@ -58,7 +46,7 @@ export const head = async (fetch: Fetch, address: string): Promise<Response> =>

export const post = async (
fetch: Fetch,
address: string,
host: string,
data?: Record<string, unknown> | BodyInit,
): Promise<Response> => {
const isRecord = (input: any): input is Record<string, unknown> => {
Expand All @@ -67,7 +55,7 @@ export const post = async (

const formattedData = isRecord(data) ? JSON.stringify(data) : data

const response = await fetch(formatAddress(address), {
const response = await fetch(host, {
method: 'POST',
body: formattedData,
})
Expand All @@ -79,10 +67,10 @@ export const post = async (

export const del = async (
fetch: Fetch,
address: string,
host: string,
data?: Record<string, unknown>,
): Promise<Response> => {
const response = await fetch(formatAddress(address), {
const response = await fetch(host, {
method: 'DELETE',
body: JSON.stringify(data),
})
Expand Down Expand Up @@ -123,3 +111,41 @@ export const parseJSON = async function* <T = unknown>(
}
}
}

export const formatHost = (host: string): string => {
if (!host) {
return 'http://127.0.0.1:11434'
}

let isExplicitProtocol = host.includes('://')

if (host.startsWith(':')) {
// if host starts with ':', prepend the default hostname
host = `http://127.0.0.1${host}`
isExplicitProtocol = false
}

if (!isExplicitProtocol) {
host = `http://${host}`
}

const url = new URL(host)

let port = url.port
if (!port) {
if (!isExplicitProtocol) {
port = '11434'
} else {
// Assign default ports based on the protocol
port = url.protocol === 'https:' ? '443' : '80'
}
}

let formattedHost = `${url.protocol}//${url.hostname}:${port}${url.pathname}`
// remove trailing slashes
if (formattedHost.endsWith('/')) {
formattedHost = formattedHost.slice(0, -1)
}

return formattedHost
}
56 changes: 54 additions & 2 deletions test/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,55 @@
describe('Empty test', () => {
it('runs', () => {})
import { formatHost } from '../src/utils'

describe('formatHost Function Tests', () => {
it('should return default URL for empty string', () => {
expect(formatHost('')).toBe('http://127.0.0.1:11434')
})

it('should parse plain IP address', () => {
expect(formatHost('1.2.3.4')).toBe('http://1.2.3.4:11434')
})

it('should parse IP address with port', () => {
expect(formatHost('1.2.3.4:56789')).toBe('http://1.2.3.4:56789')
})

it('should parse HTTP URL', () => {
expect(formatHost('http://1.2.3.4')).toBe('http://1.2.3.4:80')
})

it('should parse HTTPS URL', () => {
expect(formatHost('https://1.2.3.4')).toBe('https://1.2.3.4:443')
})

it('should parse HTTPS URL with port', () => {
expect(formatHost('https://1.2.3.4:56789')).toBe('https://1.2.3.4:56789')
})

it('should parse domain name', () => {
expect(formatHost('example.com')).toBe('http://example.com:11434')
})

it('should parse domain name with port', () => {
expect(formatHost('example.com:56789')).toBe('http://example.com:56789')
})

it('should parse HTTP domain', () => {
expect(formatHost('http://example.com')).toBe('http://example.com:80')
})

it('should parse HTTPS domain', () => {
expect(formatHost('https://example.com')).toBe('https://example.com:443')
})

it('should parse HTTPS domain with port', () => {
expect(formatHost('https://example.com:56789')).toBe('https://example.com:56789')
})

it('should handle trailing slash in domain', () => {
expect(formatHost('example.com/')).toBe('http://example.com:11434')
})

it('should handle trailing slash in domain with port', () => {
expect(formatHost('example.com:56789/')).toBe('http://example.com:56789')
})
})

0 comments on commit 097fdf3

Please sign in to comment.