Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Headers #158

Merged
merged 3 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 26 additions & 12 deletions src/browser.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as utils from './utils.js'
import { AbortableAsyncIterator, parseJSON, post } from './utils.js'
import { AbortableAsyncIterator, parseJSON } from './utils.js'
import 'whatwg-fetch'

import type {
Expand Down Expand Up @@ -34,15 +34,14 @@
constructor(config?: Partial<Config>) {
this.config = {
host: '',
headers: config?.headers
}

if (!config?.proxy) {
this.config.host = utils.formatHost(config?.host ?? 'http://127.0.0.1:11434')
}

this.fetch = fetch
if (config?.fetch != null) {
this.fetch = config.fetch
}
this.fetch = config?.fetch ?? fetch
}

// Abort any ongoing streamed requests to Ollama
Expand All @@ -66,13 +65,13 @@
*/
protected async processStreamableRequest<T extends object>(
endpoint: string,
request: { stream?: boolean } & Record<string, any>,

Check warning on line 68 in src/browser.ts

View workflow job for this annotation

GitHub Actions / test (16)

Unexpected any. Specify a different type

Check warning on line 68 in src/browser.ts

View workflow job for this annotation

GitHub Actions / test (18)

Unexpected any. Specify a different type

Check warning on line 68 in src/browser.ts

View workflow job for this annotation

GitHub Actions / test (20)

Unexpected any. Specify a different type
): Promise<T | AbortableAsyncIterator<T>> {
request.stream = request.stream ?? false
const host = `${this.config.host}/api/${endpoint}`
if (request.stream) {
const abortController = new AbortController()
const response = await post(this.fetch, host, request, {
const response = await utils.post(this.fetch, host, request, {
signal: abortController.signal,
headers: this.config.headers
})
Expand Down Expand Up @@ -236,9 +235,12 @@
* @returns {Promise<StatusResponse>} - The response object.
*/
async delete(request: DeleteRequest): Promise<StatusResponse> {
await utils.del(this.fetch, `${this.config.host}/api/delete`, {
name: request.model,
})
await utils.del(
this.fetch,
`${this.config.host}/api/delete`,
{ name: request.model },
{ headers: this.config.headers }
)
return { status: 'success' }
}

Expand All @@ -249,7 +251,9 @@
* @returns {Promise<StatusResponse>} - The response object.
*/
async copy(request: CopyRequest): Promise<StatusResponse> {
await utils.post(this.fetch, `${this.config.host}/api/copy`, { ...request })
await utils.post(this.fetch, `${this.config.host}/api/copy`, { ...request }, {
headers: this.config.headers
})
return { status: 'success' }
}

Expand All @@ -259,7 +263,9 @@
* @throws {Error} - If the response body is missing.
*/
async list(): Promise<ListResponse> {
const response = await utils.get(this.fetch, `${this.config.host}/api/tags`)
const response = await utils.get(this.fetch, `${this.config.host}/api/tags`, {
headers: this.config.headers
})
return (await response.json()) as ListResponse
}

Expand All @@ -271,6 +277,8 @@
async show(request: ShowRequest): Promise<ShowResponse> {
const response = await utils.post(this.fetch, `${this.config.host}/api/show`, {
...request,
}, {
headers: this.config.headers
})
return (await response.json()) as ShowResponse
}
Expand All @@ -283,6 +291,8 @@
async embed(request: EmbedRequest): Promise<EmbedResponse> {
const response = await utils.post(this.fetch, `${this.config.host}/api/embed`, {
...request,
}, {
headers: this.config.headers
})
return (await response.json()) as EmbedResponse
}
Expand All @@ -295,6 +305,8 @@
async embeddings(request: EmbeddingsRequest): Promise<EmbeddingsResponse> {
const response = await utils.post(this.fetch, `${this.config.host}/api/embeddings`, {
...request,
}, {
headers: this.config.headers
})
return (await response.json()) as EmbeddingsResponse
}
Expand All @@ -305,7 +317,9 @@
* @throws {Error} - If the response body is missing.
*/
async ps(): Promise<ListResponse> {
const response = await utils.get(this.fetch, `${this.config.host}/api/ps`)
const response = await utils.get(this.fetch, `${this.config.host}/api/ps`, {
headers: this.config.headers
})
return (await response.json()) as ListResponse
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
host: string
fetch?: Fetch
proxy?: boolean
headers?: Headers
headers?: HeadersInit
}

// request types
Expand Down Expand Up @@ -71,7 +71,7 @@
function: {
name: string;
arguments: {
[key: string]: any;

Check warning on line 74 in src/interfaces.ts

View workflow job for this annotation

GitHub Actions / test (16)

Unexpected any. Specify a different type

Check warning on line 74 in src/interfaces.ts

View workflow job for this annotation

GitHub Actions / test (18)

Unexpected any. Specify a different type

Check warning on line 74 in src/interfaces.ts

View workflow job for this annotation

GitHub Actions / test (20)

Unexpected any. Specify a different type
};
};
}
Expand Down Expand Up @@ -234,8 +234,8 @@
details: ModelDetails
messages: Message[]
modified_at: Date
model_info: Map<string, any>

Check warning on line 237 in src/interfaces.ts

View workflow job for this annotation

GitHub Actions / test (16)

Unexpected any. Specify a different type

Check warning on line 237 in src/interfaces.ts

View workflow job for this annotation

GitHub Actions / test (18)

Unexpected any. Specify a different type

Check warning on line 237 in src/interfaces.ts

View workflow job for this annotation

GitHub Actions / test (20)

Unexpected any. Specify a different type
projector_info?: Map<string, any>

Check warning on line 238 in src/interfaces.ts

View workflow job for this annotation

GitHub Actions / test (16)

Unexpected any. Specify a different type

Check warning on line 238 in src/interfaces.ts

View workflow job for this annotation

GitHub Actions / test (18)

Unexpected any. Specify a different type

Check warning on line 238 in src/interfaces.ts

View workflow job for this annotation

GitHub Actions / test (20)

Unexpected any. Specify a different type
}

export interface ListResponse {
Expand Down
19 changes: 14 additions & 5 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
yield message
// message will be done in the case of chat and generate
// message will be success in the case of a progress response (pull, push, create)
if ((message as any).done || (message as any).status === 'success') {

Check warning on line 48 in src/utils.ts

View workflow job for this annotation

GitHub Actions / test (16)

Unexpected any. Specify a different type

Check warning on line 48 in src/utils.ts

View workflow job for this annotation

GitHub Actions / test (16)

Unexpected any. Specify a different type

Check warning on line 48 in src/utils.ts

View workflow job for this annotation

GitHub Actions / test (18)

Unexpected any. Specify a different type

Check warning on line 48 in src/utils.ts

View workflow job for this annotation

GitHub Actions / test (18)

Unexpected any. Specify a different type

Check warning on line 48 in src/utils.ts

View workflow job for this annotation

GitHub Actions / test (20)

Unexpected any. Specify a different type

Check warning on line 48 in src/utils.ts

View workflow job for this annotation

GitHub Actions / test (20)

Unexpected any. Specify a different type
this.doneCallback()
return
}
Expand Down Expand Up @@ -115,15 +115,20 @@
'Content-Type': 'application/json',
Accept: 'application/json',
'User-Agent': `ollama-js/${version} (${getPlatform()})`,
}
} as HeadersInit

if (!options.headers) {
options.headers = {}
}

// Filter out default headers from custom headers
const customHeaders = Object.fromEntries(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bringing to parity with python sdk impl. For ref: ollama/ollama-python#313

Object.entries(options.headers).filter(([key]) => !Object.keys(defaultHeaders).some(defaultKey => defaultKey.toLowerCase() === key.toLowerCase()))
)

options.headers = {
...defaultHeaders,
...options.headers,
...customHeaders
}

return fetch(url, options)
Expand All @@ -135,8 +140,10 @@
* @param host {string} - The host to fetch
* @returns {Promise<Response>} - The fetch response
*/
export const get = async (fetch: Fetch, host: string): Promise<Response> => {
const response = await fetchWithHeaders(fetch, host)
export const get = async (fetch: Fetch, host: string, options?: { headers?: HeadersInit }): Promise<Response> => {
const response = await fetchWithHeaders(fetch, host, {
headers: options?.headers
})

await checkOk(response)

Expand Down Expand Up @@ -169,9 +176,9 @@
fetch: Fetch,
host: string,
data?: Record<string, unknown> | BodyInit,
options?: { signal?: AbortSignal, headers?: Headers },
options?: { signal?: AbortSignal, headers?: HeadersInit },
): Promise<Response> => {
const isRecord = (input: any): input is Record<string, unknown> => {

Check warning on line 181 in src/utils.ts

View workflow job for this annotation

GitHub Actions / test (16)

Unexpected any. Specify a different type

Check warning on line 181 in src/utils.ts

View workflow job for this annotation

GitHub Actions / test (18)

Unexpected any. Specify a different type

Check warning on line 181 in src/utils.ts

View workflow job for this annotation

GitHub Actions / test (20)

Unexpected any. Specify a different type
return input !== null && typeof input === 'object' && !Array.isArray(input)
}

Expand Down Expand Up @@ -199,10 +206,12 @@
fetch: Fetch,
host: string,
data?: Record<string, unknown>,
options?: { headers?: HeadersInit },
): Promise<Response> => {
const response = await fetchWithHeaders(fetch, host, {
method: 'DELETE',
body: JSON.stringify(data),
headers: options?.headers
})

await checkOk(response)
Expand Down
Loading