Skip to content

Commit 09198f1

Browse files
Graden ReaGraden Rea
Graden Rea
authored and
Graden Rea
committed
Add Streaming support
1 parent a6c643b commit 09198f1

File tree

4 files changed

+548
-3
lines changed

4 files changed

+548
-3
lines changed

Diff for: src/core.ts

+16
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { VERSION } from './version';
2+
import { Stream } from './lib/streaming';
23
import {
34
GroqError,
45
APIError,
@@ -38,6 +39,19 @@ type APIResponseProps = {
3839

3940
async function defaultParseResponse<T>(props: APIResponseProps): Promise<T> {
4041
const { response } = props;
42+
if (props.options.stream) {
43+
debug('response', response.status, response.url, response.headers, response.body);
44+
45+
// Note: there is an invariant here that isn't represented in the type system
46+
// that if you set `stream: true` the response type must also be `Stream<T>`
47+
48+
if (props.options.__streamClass) {
49+
return props.options.__streamClass.fromSSEResponse(response, props.controller) as any;
50+
}
51+
52+
return Stream.fromSSEResponse(response, props.controller) as any;
53+
}
54+
4155
// fetch refuses to read the body when the status code is 204.
4256
if (response.status === 204) {
4357
return null as T;
@@ -736,6 +750,7 @@ export type RequestOptions<Req = unknown | Record<string, unknown> | Readable> =
736750
idempotencyKey?: string;
737751

738752
__binaryResponse?: boolean | undefined;
753+
__streamClass?: typeof Stream;
739754
};
740755

741756
// This is required so that we can determine if a given object matches the RequestOptions
@@ -756,6 +771,7 @@ const requestOptionsKeys: KeysEnum<RequestOptions> = {
756771
idempotencyKey: true,
757772

758773
__binaryResponse: true,
774+
__streamClass: true,
759775
};
760776

761777
export const isRequestOptions = (obj: unknown): obj is RequestOptions => {

Diff for: src/lib/chat_completions_ext.ts

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Manually curated models for streaming chat completions.
2+
3+
export interface ChatCompletionChunk {
4+
id: string;
5+
6+
choices: Array<ChatCompletionChunk.Choice>;
7+
8+
created: number;
9+
10+
model: string;
11+
12+
object: 'chat.completion.chunk';
13+
14+
system_fingerprint?: string;
15+
}
16+
17+
export namespace ChatCompletionChunk {
18+
export interface Choice {
19+
delta: Choice.Delta;
20+
21+
finish_reason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | 'function_call' | null;
22+
23+
index: number;
24+
25+
logprobs?: Choice.Logprobs | null;
26+
}
27+
28+
export namespace Choice {
29+
export interface Delta {
30+
content?: string | null;
31+
32+
function_call?: Delta.FunctionCall;
33+
34+
role?: 'system' | 'user' | 'assistant' | 'tool';
35+
36+
tool_calls?: Array<Delta.ToolCall>;
37+
}
38+
39+
export namespace Delta {
40+
export interface FunctionCall {
41+
arguments?: string;
42+
43+
name?: string;
44+
}
45+
46+
export interface ToolCall {
47+
index: number;
48+
49+
id?: string;
50+
51+
function?: ToolCall.Function;
52+
53+
type?: 'function';
54+
}
55+
56+
export namespace ToolCall {
57+
export interface Function {
58+
arguments?: string;
59+
60+
name?: string;
61+
}
62+
}
63+
}
64+
65+
export interface Logprobs {
66+
content: Array<ChatCompletionTokenLogprob> | null;
67+
}
68+
}
69+
}
70+
71+
export interface ChatCompletionTokenLogprob {
72+
token: string;
73+
74+
bytes: Array<number> | null;
75+
76+
logprob: number;
77+
78+
top_logprobs: Array<ChatCompletionTokenLogprob.TopLogprob>;
79+
}
80+
81+
export namespace ChatCompletionTokenLogprob {
82+
export interface TopLogprob {
83+
token: string;
84+
85+
bytes: Array<number> | null;
86+
87+
logprob: number;
88+
}
89+
}

0 commit comments

Comments
 (0)