generated from SAP/repository-template
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* debug code * Make streaming work * fix: remove await * fix: await again * small changes * chore: add missing javadoc * wip * feat: pipe streams * feat: wrap chunk to see usage and finish reason * refactor: pipe streams * refactor * refactor: change streamString to streamContent * fix: lint * refactor * feat: demo streaming in sample-code * fix: end res in sample code when finish * fix: lint * refactor * fix: check public-api * chore: add tests for stream chunk response * fix: Changes from lint * fix: chunk type inference * refactor: change some types * wip * fix: internal.js.map issue * chore: add tests for chat completion stream * refactor: move stream files * fix: remove duplicated file * refactor: rename stream * refactor: openai stream * chore: add tests for sse-stream (copied from openai) * refactor: rename test responses * refactor: replace streamContent with a method * feat: support multiple choices * fix: Changes from lint * fix: add abortcontroler and fix sample code * fix: add controller signal to axios * fix: Changes from lint * chore: add unit test for stream() * fix: Changes from lint * fix: stream finish reason index 0 * lint * fix: type test * fix: make toContentStream return AzureOpenAiChatCompletionStream * fix: lint * feat: throw if sse payload invalid * fix: Changes from lint * refactor: interface * refactor * chore: add changeset * chore: improve sample code for streaming * fix: Changes from lint * docs * refactor: get by index * fix: lint * chore: small changes * fix: Changes from lint * fix: type of finish reason * Update packages/foundation-models/src/azure-openai/stream/line-decoder.ts Co-authored-by: KavithaSiva <[email protected]> * Update .changeset/seven-chairs-change.md Co-authored-by: KavithaSiva <[email protected]> * Update packages/foundation-models/src/azure-openai/azure-openai-chat-client.ts * fix: get token usage return type * chore: comment finish reasons map * refactor: code review * fix: ignore _ in eslint * Update packages/foundation-models/src/azure-openai/azure-openai-chat-completion-stream.ts Co-authored-by: Tom Frenken <[email protected]> --------- Co-authored-by: cloud-sdk-js <[email protected]> Co-authored-by: Junjie Tang <[email protected]> Co-authored-by: KavithaSiva <[email protected]> Co-authored-by: Tom Frenken <[email protected]>
- Loading branch information
1 parent
b900c46
commit 71b1a52
Showing
25 changed files
with
1,501 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@sap-ai-sdk/foundation-models': minor | ||
--- | ||
|
||
[New Functionality] Support streaming chat completion in the Azure OpenAI client in `foundation-models`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
...dation-models/src/azure-openai/azure-openai-chat-completion-stream-chunk-response.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import { parseMockResponse } from '../../../../test-util/mock-http.js'; | ||
import { AzureOpenAiChatCompletionStreamChunkResponse } from './azure-openai-chat-completion-stream-chunk-response.js'; | ||
|
||
describe('OpenAI chat completion stream chunk response', () => { | ||
let mockResponses: { | ||
tokenUsageResponse: any; | ||
finishReasonResponse: any; | ||
deltaContentResponse: any; | ||
}; | ||
let azureOpenAiChatCompletionStreamChunkResponses: { | ||
tokenUsageResponse: AzureOpenAiChatCompletionStreamChunkResponse; | ||
finishReasonResponse: AzureOpenAiChatCompletionStreamChunkResponse; | ||
deltaContentResponse: AzureOpenAiChatCompletionStreamChunkResponse; | ||
}; | ||
|
||
beforeAll(async () => { | ||
mockResponses = { | ||
tokenUsageResponse: await parseMockResponse<any>( | ||
'foundation-models', | ||
'azure-openai-chat-completion-stream-chunk-response-token-usage.json' | ||
), | ||
finishReasonResponse: await parseMockResponse<any>( | ||
'foundation-models', | ||
'azure-openai-chat-completion-stream-chunk-response-finish-reason.json' | ||
), | ||
deltaContentResponse: await parseMockResponse<any>( | ||
'foundation-models', | ||
'azure-openai-chat-completion-stream-chunk-response-delta-content.json' | ||
) | ||
}; | ||
azureOpenAiChatCompletionStreamChunkResponses = { | ||
tokenUsageResponse: new AzureOpenAiChatCompletionStreamChunkResponse( | ||
mockResponses.tokenUsageResponse | ||
), | ||
finishReasonResponse: new AzureOpenAiChatCompletionStreamChunkResponse( | ||
mockResponses.finishReasonResponse | ||
), | ||
deltaContentResponse: new AzureOpenAiChatCompletionStreamChunkResponse( | ||
mockResponses.deltaContentResponse | ||
) | ||
}; | ||
}); | ||
|
||
it('should return the chat completion stream chunk response', () => { | ||
expect( | ||
azureOpenAiChatCompletionStreamChunkResponses.tokenUsageResponse.data | ||
).toStrictEqual(mockResponses.tokenUsageResponse); | ||
expect( | ||
azureOpenAiChatCompletionStreamChunkResponses.finishReasonResponse.data | ||
).toStrictEqual(mockResponses.finishReasonResponse); | ||
expect( | ||
azureOpenAiChatCompletionStreamChunkResponses.deltaContentResponse.data | ||
).toStrictEqual(mockResponses.deltaContentResponse); | ||
}); | ||
|
||
it('should get token usage', () => { | ||
expect( | ||
azureOpenAiChatCompletionStreamChunkResponses.tokenUsageResponse.getTokenUsage() | ||
).toMatchObject({ | ||
completion_tokens: expect.any(Number), | ||
prompt_tokens: expect.any(Number), | ||
total_tokens: expect.any(Number) | ||
}); | ||
}); | ||
|
||
it('should return finish reason', () => { | ||
expect( | ||
azureOpenAiChatCompletionStreamChunkResponses.finishReasonResponse.getFinishReason() | ||
).toBe('stop'); | ||
}); | ||
|
||
it('should return delta content with default index 0', () => { | ||
expect( | ||
azureOpenAiChatCompletionStreamChunkResponses.deltaContentResponse.getDeltaContent() | ||
).toBe(' is'); | ||
}); | ||
}); |
39 changes: 39 additions & 0 deletions
39
.../foundation-models/src/azure-openai/azure-openai-chat-completion-stream-chunk-response.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import type { AzureOpenAiCompletionUsage } from './client/inference/schema/index.js'; | ||
|
||
/** | ||
* Azure OpenAI chat completion stream chunk response. | ||
*/ | ||
export class AzureOpenAiChatCompletionStreamChunkResponse { | ||
constructor(public readonly data: any) { | ||
// TODO: Change `any` to `CreateChatCompletionStreamResponse` once the preview spec becomes stable. | ||
this.data = data; | ||
} | ||
|
||
/** | ||
* Usage of tokens in the chunk response. | ||
* @returns Token usage. | ||
*/ | ||
getTokenUsage(): AzureOpenAiCompletionUsage | null { | ||
return this.data.usage; | ||
} | ||
|
||
/** | ||
* Reason for stopping the completion stream chunk. | ||
* @param choiceIndex - The index of the choice to parse. | ||
* @returns The finish reason. | ||
*/ | ||
getFinishReason(choiceIndex = 0): string | undefined { | ||
return this.data.choices.find((c: any) => c.index === choiceIndex) | ||
?.finish_reason; | ||
} | ||
|
||
/** | ||
* Parses the chunk response and returns the delta content. | ||
* @param choiceIndex - The index of the choice to parse. | ||
* @returns The message delta content. | ||
*/ | ||
getDeltaContent(choiceIndex = 0): string | undefined | null { | ||
return this.data.choices.find((c: any) => c.index === choiceIndex)?.delta | ||
.content; | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
packages/foundation-models/src/azure-openai/azure-openai-chat-completion-stream-response.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import type { AzureOpenAiCompletionUsage } from './client/inference/schema/index.js'; | ||
import type { AzureOpenAiChatCompletionStream } from './azure-openai-chat-completion-stream.js'; | ||
|
||
/** | ||
* Azure OpenAI chat completion stream response. | ||
*/ | ||
export class AzureOpenAiChatCompletionStreamResponse<T> { | ||
private _usage: AzureOpenAiCompletionUsage | undefined; | ||
/** | ||
* Finish reasons for all choices. | ||
*/ | ||
private _finishReasons: Map<number, string> = new Map(); | ||
private _stream: AzureOpenAiChatCompletionStream<T> | undefined; | ||
|
||
public getTokenUsage(): AzureOpenAiCompletionUsage | undefined { | ||
return this._usage; | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
_setTokenUsage(usage: AzureOpenAiCompletionUsage): void { | ||
this._usage = usage; | ||
} | ||
|
||
public getFinishReason(choiceIndex = 0): string | undefined | null { | ||
return this._finishReasons.get(choiceIndex); | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
_getFinishReasons(): Map<number, string> { | ||
return this._finishReasons; | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
_setFinishReasons(finishReasons: Map<number, string>): void { | ||
this._finishReasons = finishReasons; | ||
} | ||
|
||
get stream(): AzureOpenAiChatCompletionStream<T> { | ||
if (!this._stream) { | ||
throw new Error('Response stream is undefined.'); | ||
} | ||
return this._stream; | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
set stream(stream: AzureOpenAiChatCompletionStream<T>) { | ||
this._stream = stream; | ||
} | ||
} |
Oops, something went wrong.