diff --git a/src/client.ts b/src/client.ts index f55a6b986e..af264492f1 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1032,6 +1032,9 @@ export class OpenAI { 'X-Stainless-Retry-Count': String(retryCount), ...(options.timeout ? { 'X-Stainless-Timeout': String(Math.trunc(options.timeout / 1000)) } : {}), ...getPlatformHeaders(), + ...(typeof options.__metadata?.helperMethod === 'string' ? + { 'X-Stainless-Helper-Method': options.__metadata.helperMethod } + : {}), 'OpenAI-Organization': this.organization, 'OpenAI-Project': this.project, }, diff --git a/src/lib/AssistantStream.ts b/src/lib/AssistantStream.ts index bb2a2b5b36..9c66986709 100644 --- a/src/lib/AssistantStream.ts +++ b/src/lib/AssistantStream.ts @@ -196,7 +196,7 @@ export class AssistantStream runner._run(() => runner._runToolAssistantStream(runId, runs, params, { ...options, - headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' }, + __metadata: { ...options?.__metadata, helperMethod: 'stream' }, }), ); return runner; @@ -241,7 +241,7 @@ export class AssistantStream runner._run(() => runner._threadAssistantStream(params, thread, { ...options, - headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' }, + __metadata: { ...options?.__metadata, helperMethod: 'stream' }, }), ); return runner; @@ -257,7 +257,7 @@ export class AssistantStream runner._run(() => runner._runAssistantStream(threadId, runs, params, { ...options, - headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' }, + __metadata: { ...options?.__metadata, helperMethod: 'stream' }, }), ); return runner; diff --git a/src/lib/ChatCompletionRunner.ts b/src/lib/ChatCompletionRunner.ts index a5edaf7411..f6f8673c50 100644 --- a/src/lib/ChatCompletionRunner.ts +++ b/src/lib/ChatCompletionRunner.ts @@ -35,7 +35,7 @@ export class ChatCompletionRunner extends AbstractChatCompletion const runner = new ChatCompletionRunner(); const opts = { ...options, - headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'runTools' }, + __metadata: { ...options?.__metadata, helperMethod: 'runTools' }, }; runner._run(() => runner._runTools(client, params, opts)); return runner; diff --git a/src/lib/ChatCompletionStream.ts b/src/lib/ChatCompletionStream.ts index 6dc5bc6c42..578e655038 100644 --- a/src/lib/ChatCompletionStream.ts +++ b/src/lib/ChatCompletionStream.ts @@ -167,7 +167,7 @@ export class ChatCompletionStream runner._runChatCompletion( client, { ...params, stream: true }, - { ...options, headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' } }, + { ...options, __metadata: { ...options?.__metadata, helperMethod: 'stream' } }, ), ); return runner; diff --git a/src/lib/ChatCompletionStreamingRunner.ts b/src/lib/ChatCompletionStreamingRunner.ts index eb8fcc3579..4fd96b5344 100644 --- a/src/lib/ChatCompletionStreamingRunner.ts +++ b/src/lib/ChatCompletionStreamingRunner.ts @@ -42,7 +42,7 @@ export class ChatCompletionStreamingRunner ); const opts = { ...options, - headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'runTools' }, + __metadata: { ...options?.__metadata, helperMethod: 'runTools' }, }; runner._run(() => runner._runTools(client, params, opts)); return runner; diff --git a/src/lib/responses/ResponseStream.ts b/src/lib/responses/ResponseStream.ts index 652c81ceda..fcc3dc3b8b 100644 --- a/src/lib/responses/ResponseStream.ts +++ b/src/lib/responses/ResponseStream.ts @@ -83,7 +83,7 @@ export class ResponseStream runner._run(() => runner._createOrRetrieveResponse(client, params, { ...options, - headers: { ...options?.headers, 'X-Stainless-Helper-Method': 'stream' }, + __metadata: { ...options?.__metadata, helperMethod: 'stream' }, }), ); return runner; diff --git a/src/resources/chat/completions/completions.ts b/src/resources/chat/completions/completions.ts index efc491e6c9..72350354e8 100644 --- a/src/resources/chat/completions/completions.ts +++ b/src/resources/chat/completions/completions.ts @@ -153,10 +153,7 @@ export class Completions extends APIResource { return this._client.chat.completions .create(body, { ...options, - headers: { - ...options?.headers, - 'X-Stainless-Helper-Method': 'chat.completions.parse', - }, + __metadata: { ...options?.__metadata, helperMethod: 'chat.completions.parse' }, }) ._thenUnwrap((completion) => parseChatCompletion(completion, body)); } diff --git a/tests/lib/ChatCompletionRunFunctions.test.ts b/tests/lib/ChatCompletionRunFunctions.test.ts index f14257ccd3..257d506388 100644 --- a/tests/lib/ChatCompletionRunFunctions.test.ts +++ b/tests/lib/ChatCompletionRunFunctions.test.ts @@ -18,13 +18,16 @@ function mockChatCompletionFetch() { const { fetch, handleRequest: handleRawRequest } = mockFetch(); function handleRequest( - handler: (body: ChatCompletionToolRunnerParams) => Promise, + handler: ( + body: ChatCompletionToolRunnerParams, + init: RequestInit | undefined, + ) => Promise, ): Promise { return handleRawRequest(async (req, init) => { const rawBody = init?.body; if (typeof rawBody !== 'string') throw new Error(`expected init.body to be a string`); const body: ChatCompletionToolRunnerParams = JSON.parse(rawBody); - return new Response(JSON.stringify(await handler(body)), { + return new Response(JSON.stringify(await handler(body, init)), { headers: { 'Content-Type': 'application/json' }, }); }); @@ -495,6 +498,47 @@ function _typeTests() { describe('resource completions', () => { describe('runTools with stream: false', () => { + test('defaultHeaders can suppress helper method header', async () => { + const { fetch, handleRequest } = mockChatCompletionFetch(); + + const openai = new OpenAI({ + apiKey: 'something1234', + baseURL: 'http://127.0.0.1:4010', + defaultHeaders: { 'x-stainless-helper-method': null }, + fetch, + }); + + const runner = openai.chat.completions.runTools({ + messages: [{ role: 'user', content: 'say hi' }], + model: 'gpt-3.5-turbo', + tools: [], + }); + + await handleRequest(async (_request, init) => { + expect(new Headers(init?.headers).has('x-stainless-helper-method')).toBe(false); + return { + id: '1', + choices: [ + { + index: 0, + finish_reason: 'stop', + logprobs: null, + message: { + role: 'assistant', + content: 'hi', + refusal: null, + }, + }, + ], + created: Math.floor(Date.now() / 1000), + model: 'gpt-3.5-turbo', + object: 'chat.completion', + }; + }); + + await runner.done(); + }); + test('successful flow', async () => { const { fetch, handleRequest } = mockChatCompletionFetch();