Skip to content

Commit 6e7e496

Browse files
Custom Headers (#158)
* Allow users to pass custom headers Co-authored-by: Naveen <[email protected]> Co-authored-by: Bruce MacDonald <[email protected]>
1 parent c97f231 commit 6e7e496

File tree

3 files changed

+41
-18
lines changed

3 files changed

+41
-18
lines changed

src/browser.ts

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as utils from './utils.js'
2-
import { AbortableAsyncIterator, parseJSON, post } from './utils.js'
2+
import { AbortableAsyncIterator, parseJSON } from './utils.js'
33
import 'whatwg-fetch'
44

55
import type {
@@ -34,15 +34,14 @@ export class Ollama {
3434
constructor(config?: Partial<Config>) {
3535
this.config = {
3636
host: '',
37+
headers: config?.headers
3738
}
39+
3840
if (!config?.proxy) {
3941
this.config.host = utils.formatHost(config?.host ?? 'http://127.0.0.1:11434')
4042
}
4143

42-
this.fetch = fetch
43-
if (config?.fetch != null) {
44-
this.fetch = config.fetch
45-
}
44+
this.fetch = config?.fetch ?? fetch
4645
}
4746

4847
// Abort any ongoing streamed requests to Ollama
@@ -72,7 +71,7 @@ export class Ollama {
7271
const host = `${this.config.host}/api/${endpoint}`
7372
if (request.stream) {
7473
const abortController = new AbortController()
75-
const response = await post(this.fetch, host, request, {
74+
const response = await utils.post(this.fetch, host, request, {
7675
signal: abortController.signal,
7776
headers: this.config.headers
7877
})
@@ -236,9 +235,12 @@ async encodeImage(image: Uint8Array | string): Promise<string> {
236235
* @returns {Promise<StatusResponse>} - The response object.
237236
*/
238237
async delete(request: DeleteRequest): Promise<StatusResponse> {
239-
await utils.del(this.fetch, `${this.config.host}/api/delete`, {
240-
name: request.model,
241-
})
238+
await utils.del(
239+
this.fetch,
240+
`${this.config.host}/api/delete`,
241+
{ name: request.model },
242+
{ headers: this.config.headers }
243+
)
242244
return { status: 'success' }
243245
}
244246

@@ -249,7 +251,9 @@ async encodeImage(image: Uint8Array | string): Promise<string> {
249251
* @returns {Promise<StatusResponse>} - The response object.
250252
*/
251253
async copy(request: CopyRequest): Promise<StatusResponse> {
252-
await utils.post(this.fetch, `${this.config.host}/api/copy`, { ...request })
254+
await utils.post(this.fetch, `${this.config.host}/api/copy`, { ...request }, {
255+
headers: this.config.headers
256+
})
253257
return { status: 'success' }
254258
}
255259

@@ -259,7 +263,9 @@ async encodeImage(image: Uint8Array | string): Promise<string> {
259263
* @throws {Error} - If the response body is missing.
260264
*/
261265
async list(): Promise<ListResponse> {
262-
const response = await utils.get(this.fetch, `${this.config.host}/api/tags`)
266+
const response = await utils.get(this.fetch, `${this.config.host}/api/tags`, {
267+
headers: this.config.headers
268+
})
263269
return (await response.json()) as ListResponse
264270
}
265271

@@ -271,6 +277,8 @@ async encodeImage(image: Uint8Array | string): Promise<string> {
271277
async show(request: ShowRequest): Promise<ShowResponse> {
272278
const response = await utils.post(this.fetch, `${this.config.host}/api/show`, {
273279
...request,
280+
}, {
281+
headers: this.config.headers
274282
})
275283
return (await response.json()) as ShowResponse
276284
}
@@ -283,6 +291,8 @@ async encodeImage(image: Uint8Array | string): Promise<string> {
283291
async embed(request: EmbedRequest): Promise<EmbedResponse> {
284292
const response = await utils.post(this.fetch, `${this.config.host}/api/embed`, {
285293
...request,
294+
}, {
295+
headers: this.config.headers
286296
})
287297
return (await response.json()) as EmbedResponse
288298
}
@@ -295,6 +305,8 @@ async encodeImage(image: Uint8Array | string): Promise<string> {
295305
async embeddings(request: EmbeddingsRequest): Promise<EmbeddingsResponse> {
296306
const response = await utils.post(this.fetch, `${this.config.host}/api/embeddings`, {
297307
...request,
308+
}, {
309+
headers: this.config.headers
298310
})
299311
return (await response.json()) as EmbeddingsResponse
300312
}
@@ -305,7 +317,9 @@ async encodeImage(image: Uint8Array | string): Promise<string> {
305317
* @throws {Error} - If the response body is missing.
306318
*/
307319
async ps(): Promise<ListResponse> {
308-
const response = await utils.get(this.fetch, `${this.config.host}/api/ps`)
320+
const response = await utils.get(this.fetch, `${this.config.host}/api/ps`, {
321+
headers: this.config.headers
322+
})
309323
return (await response.json()) as ListResponse
310324
}
311325
}

src/interfaces.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export interface Config {
44
host: string
55
fetch?: Fetch
66
proxy?: boolean
7-
headers?: Headers
7+
headers?: HeadersInit
88
}
99

1010
// request types

src/utils.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,20 @@ const fetchWithHeaders = async (
115115
'Content-Type': 'application/json',
116116
Accept: 'application/json',
117117
'User-Agent': `ollama-js/${version} (${getPlatform()})`,
118-
}
118+
} as HeadersInit
119119

120120
if (!options.headers) {
121121
options.headers = {}
122122
}
123123

124+
// Filter out default headers from custom headers
125+
const customHeaders = Object.fromEntries(
126+
Object.entries(options.headers).filter(([key]) => !Object.keys(defaultHeaders).some(defaultKey => defaultKey.toLowerCase() === key.toLowerCase()))
127+
)
128+
124129
options.headers = {
125130
...defaultHeaders,
126-
...options.headers,
131+
...customHeaders
127132
}
128133

129134
return fetch(url, options)
@@ -135,8 +140,10 @@ const fetchWithHeaders = async (
135140
* @param host {string} - The host to fetch
136141
* @returns {Promise<Response>} - The fetch response
137142
*/
138-
export const get = async (fetch: Fetch, host: string): Promise<Response> => {
139-
const response = await fetchWithHeaders(fetch, host)
143+
export const get = async (fetch: Fetch, host: string, options?: { headers?: HeadersInit }): Promise<Response> => {
144+
const response = await fetchWithHeaders(fetch, host, {
145+
headers: options?.headers
146+
})
140147

141148
await checkOk(response)
142149

@@ -169,7 +176,7 @@ export const post = async (
169176
fetch: Fetch,
170177
host: string,
171178
data?: Record<string, unknown> | BodyInit,
172-
options?: { signal?: AbortSignal, headers?: Headers },
179+
options?: { signal?: AbortSignal, headers?: HeadersInit },
173180
): Promise<Response> => {
174181
const isRecord = (input: any): input is Record<string, unknown> => {
175182
return input !== null && typeof input === 'object' && !Array.isArray(input)
@@ -199,10 +206,12 @@ export const del = async (
199206
fetch: Fetch,
200207
host: string,
201208
data?: Record<string, unknown>,
209+
options?: { headers?: HeadersInit },
202210
): Promise<Response> => {
203211
const response = await fetchWithHeaders(fetch, host, {
204212
method: 'DELETE',
205213
body: JSON.stringify(data),
214+
headers: options?.headers
206215
})
207216

208217
await checkOk(response)

0 commit comments

Comments
 (0)