Skip to content

Commit 3f0dc74

Browse files
committed
update openai response and stream handling
1 parent da15aec commit 3f0dc74

File tree

14 files changed

+441
-49
lines changed

14 files changed

+441
-49
lines changed

examples/openai-chat-stream.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ const job = openai()
44
.chat("gpt-4o-mini")
55
.prompt("generate a 50 words text")
66
.stream();
7-
const stream = await job.run();
8-
for await (const chunk of stream) {
9-
process.stdout.write(text(chunk));
7+
for await (const chunk of job) {
8+
console.log(chunk?.message);
109
}

examples/openai-chat.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ const job = openai({})
44
.chat("gpt-4o-mini")
55
.messages([system("you are a helpful assistant"), user("hi")]);
66
const result = await job.run();
7-
console.log(text(result));
7+
console.log(result?.message);

examples/openai-embedding.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ import { openai } from "../src";
22

33
const job = openai().embedding("text-embedding-3-small").value("hello");
44
const result = await job.run();
5-
console.log(result.embedding);
5+
console.log(result!.embedding);

examples/openai-models.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ import { openai } from "../src";
22

33
const job = openai().models();
44
const result = await job.run();
5-
for (const model of result.raw.data) {
6-
console.log(model.id);
5+
for (const model of result!) {
6+
console.log(model);
77
}

src/jobs/builder.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@ export abstract class JobBuilder<Job extends BaseJob> {
2222
performance?: Job["performance"]; // TODO: track job performance
2323

2424
abstract makeRequest(): Request;
25-
abstract handleResponse(
26-
response: Response,
27-
): Promise<Job["output"] | AsyncGenerator<Job["output"]>>;
2825

29-
async run(): Promise<Job["output"] | AsyncGenerator<Job["output"]>> {
26+
27+
async handleResponse(response: Response): Promise<Job["output"]> {
28+
throw new Error("Not implemented");
29+
}
30+
31+
async run(): Promise<Job["output"]> {
3032
const request = this.makeRequest!();
3133
const response = await fetch(request);
3234
if (!response.ok) {
@@ -43,6 +45,7 @@ export abstract class JobBuilder<Job extends BaseJob> {
4345
}
4446
return await this.handleResponse!(response);
4547
}
48+
4649
dump() {
4750
return {
4851
version: version,

src/jobs/chat/builder.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { z } from "zod";
2-
import { JobBuilder } from "~/jobs/builder";
2+
import { HTTPError, JobBuilder } from "~/jobs/builder";
33
import type {
44
ChatJob,
55
ChatStreamOptions,
6+
ChatToolChoiceSchema,
67
Message,
78
ResponseFormat,
89
} from "./schema";
@@ -22,6 +23,27 @@ export abstract class ChatJobBuilder<
2223
};
2324
}
2425

26+
async *handleStream(response: Response): AsyncGenerator<Job["output"]> {
27+
throw new Error("Not implemented");
28+
}
29+
30+
async *stream(options?: ChatStreamOptions): AsyncGenerator<Job["output"]> {
31+
this.input.stream = true;
32+
this.input.streamOptions = options;
33+
if (!this.handleStream) {
34+
throw new Error("Stream not supported");
35+
}
36+
const request = this.makeRequest!();
37+
const response = await fetch(request);
38+
if (!response.ok) {
39+
throw new HTTPError(
40+
`Fetch error: ${response.statusText}`,
41+
response.status,
42+
);
43+
}
44+
yield* this.handleStream(response);
45+
}
46+
2547
system(system: string) {
2648
this.input.system = system;
2749
return this;
@@ -73,7 +95,7 @@ export abstract class ChatJobBuilder<
7395
return this;
7496
}
7597

76-
toolChoice(toolChoice: string) {
98+
toolChoice(toolChoice: z.infer<typeof ChatToolChoiceSchema>) {
7799
this.input.toolChoice = toolChoice;
78100
return this;
79101
}
@@ -92,12 +114,4 @@ export abstract class ChatJobBuilder<
92114

93115
return this;
94116
}
95-
96-
stream(streamOptions?: ChatStreamOptions) {
97-
this.input.stream = true;
98-
if (streamOptions) {
99-
this.input.streamOptions = streamOptions;
100-
}
101-
return this;
102-
}
103117
}

src/jobs/chat/schema.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ export const JsonSchemaDefSchema = z.object({
9797

9898
export const ChunkSchema = z.object({});
9999

100+
export const ChatToolChoiceSchema = z.object({
101+
mode: z.enum(["auto", "none", "any"]),
102+
allowed_tools: z.array(z.string()).optional(),
103+
});
104+
100105
export const ChatInputSchema = z.object({
101106
model: z.string(),
102107
temperature: z.number().optional(),
@@ -105,7 +110,8 @@ export const ChatInputSchema = z.object({
105110
maxTokens: z.number().optional(),
106111
messages: z.array(MessageSchema),
107112
tools: z.array(ChatToolSchema).optional(),
108-
toolChoice: z.string().optional(),
113+
//TODO: support gemini and anthropic tool choice, might need refactor
114+
toolChoice: ChatToolChoiceSchema.optional(),
109115
responseFormat: ResponseFormatSchema.optional(),
110116
topP: z.number().optional(),
111117
topK: z.number().optional(),

src/jobs/chat/utils.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import { parse } from "partial-json";
33
import type { ChatToolSchema, Message } from "./schema";
44
import { ChatTool } from "./tool";
55

6+
// TODO: move to providers, different providers have different tool formats
7+
// @deprecated
68
export function convertTools(tools: z.infer<typeof ChatToolSchema>[]) {
9+
console.warn("convertTools is deprecated, move to providers");
710
return tools.map((tool) => ({
811
type: "function",
912
function: {

src/jobs/image/builder.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,4 @@ export abstract class ImageJobBuilder<
9393
this.input.background = background;
9494
return this;
9595
}
96-
97-
stream() {
98-
this.input.stream = true;
99-
return this;
100-
}
10196
}

src/jobs/models/schema.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ import { BaseJobSchema } from "~/jobs/schema";
33

44
export const ModelsInputSchema = z.object({});
55

6-
export const ModelsOuputSchema = z.object({});
6+
export const ModelsOuputSchema = z.array(
7+
z.object({
8+
id: z.string(),
9+
created: z.number(),
10+
owned_by: z.string(),
11+
}),
12+
);
713

814
export const ModelsJobSchema = BaseJobSchema.extend({
915
type: z.literal("models"),

0 commit comments

Comments
 (0)