Skip to content

Commit f2a7e98

Browse files
committed
add job output schema
1 parent 04290b5 commit f2a7e98

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+346
-284
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ npm install fluent-ai zod
1818

1919
fluent-ai includes support for multiple AI providers and modalities.
2020

21-
| Provider | chat | embedding | image | models |
21+
| provider | chat completion | embedding | image generation | list models |
2222
| --------- | ------------------ | ------------------ | ------------------ | ------------------ |
2323
| anthropic | :white_check_mark: | | | :white_check_mark: |
2424
| fal | | | :white_check_mark: | |

bunfig.toml

Lines changed: 0 additions & 2 deletions
This file was deleted.

examples/load.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

examples/openai-chat-load.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import { load } from "../src";
33
const job = load({
44
provider: "openai",
55
type: "chat",
6-
model: "gpt-4o-mini",
7-
messages: [{ role: "user", content: "hi" }],
6+
input: {
7+
model: "gpt-4o-mini",
8+
messages: [{ role: "user", content: "hi" }],
9+
},
810
});
911
const result = await job.run();
1012
console.log(result);

examples/openai-chat-stream.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { chunkText, openai, userPrompt } from "../src";
1+
import { text, openai, userPrompt } from "../src";
22

33
const job = openai()
44
.chat("gpt-4o-mini")
@@ -7,8 +7,7 @@ const job = openai()
77

88
const stream = await job.run();
99
for await (const chunk of stream) {
10-
// console.log(chunk);
11-
process.stdout.write(chunkText(chunk));
10+
process.stdout.write(text(chunk));
1211
}
13-
const result = await job.done();
14-
console.log(result);
12+
const output = await job.done();
13+
console.log(output);

examples/openai-chat.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
import { openai, systemPrompt, userPrompt } from "../src";
1+
import { openai, systemPrompt, text, userPrompt } from "../src";
22

33
const job = openai({})
44
.chat("gpt-4o-mini")
55
.messages([systemPrompt("you are a helpful assistant"), userPrompt("hi")]);
66
const result = await job.run();
7-
console.log(JSON.stringify(result.raw, null, 2));
7+
console.log(text(result));
8+
console.log(job.cost);
9+
console.log(job.performance);

examples/openai-embedding.ts

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

3-
const job = openai().embedding("text-embedding-3-small").input("hello");
3+
const job = openai().embedding("text-embedding-3-small").value("hello");
44
const result = await job.run();
5-
console.log(JSON.stringify(result, null, 2));
5+
console.log(result.embedding);
6+
console.log(job.cost);
7+
console.log(job.performance);

src/jobs/builder.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import { version } from "../../package.json";
2-
import type { JobOptions, JobProvider } from "./schema";
2+
import type { Job } from "./load";
3+
import type {
4+
JobCost,
5+
JobOptions,
6+
JobPerformance,
7+
JobProvider,
8+
JobType,
9+
} from "./schema";
310

411
export class HTTPError extends Error {
512
status: number;
@@ -12,14 +19,19 @@ export class HTTPError extends Error {
1219
}
1320
}
1421

15-
export class JobBuilder {
22+
export class JobBuilder<Input, Output> {
1623
provider!: JobProvider;
1724
options!: JobOptions;
25+
type!: JobType;
26+
input?: Input;
27+
output?: Output;
28+
cost?: JobCost;
29+
performance?: JobPerformance; // TODO: track job performance
1830

1931
makeRequest?: () => Request;
2032
handleResponse?: (response: Response) => any;
2133

22-
async run() {
34+
async run(): Promise<Output> {
2335
const request = this.makeRequest!();
2436
const response = await fetch(request);
2537
if (!response.ok) {
@@ -45,6 +57,11 @@ export class JobBuilder {
4557
version: version,
4658
provider: this.provider,
4759
options: this.options,
48-
};
60+
type: this.type,
61+
input: this.input!,
62+
output: this.output as any,
63+
cost: this.cost,
64+
performance: this.performance,
65+
} as Job;
4966
}
5067
}

src/jobs/chat/builder.ts

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,81 @@
11
import { z } from "zod";
22
import { JobBuilder } from "~/jobs/builder";
33
import type {
4-
ChatJobSchema,
4+
ChatInput,
5+
ChatOutput,
56
ChatStreamOptions,
67
Message,
78
ResponseFormat,
89
} from "./schema";
910
import type { ChatTool } from "./tool";
1011

11-
type ChatJob = z.infer<typeof ChatJobSchema>;
12-
13-
export class ChatJobBuilder extends JobBuilder {
14-
job: ChatJob;
12+
export class ChatJobBuilder extends JobBuilder<ChatInput, ChatOutput> {
13+
input: ChatInput;
1514

1615
constructor(model: string) {
1716
super();
18-
this.job = {
19-
type: "chat",
17+
this.type = "chat";
18+
this.input = {
2019
model: model,
2120
messages: [],
2221
};
2322
}
2423

2524
systemPrompt(systemPrompt: string) {
26-
this.job.systemPrompt = systemPrompt;
25+
this.input.systemPrompt = systemPrompt;
2726
return this;
2827
}
2928

3029
messages(messages: Message[]) {
31-
this.job.messages = messages;
30+
this.input.messages = messages;
3231
return this;
3332
}
3433

3534
temperature(temperature: number) {
36-
this.job.temperature = temperature;
35+
this.input.temperature = temperature;
3736
return this;
3837
}
3938

4039
maxTokens(maxTokens: number) {
41-
this.job.maxTokens = maxTokens;
40+
this.input.maxTokens = maxTokens;
4241
return this;
4342
}
4443

4544
topP(topP: number) {
46-
this.job.topP = topP;
45+
this.input.topP = topP;
4746
return this;
4847
}
4948

5049
topK(topK: number) {
51-
this.job.topK = topK;
50+
this.input.topK = topK;
5251
return this;
5352
}
5453

5554
tools(tools: ChatTool[]) {
56-
this.job.tools = tools.map((tool) => tool.params);
55+
this.input.tools = tools.map((tool) => tool.params);
5756
return this;
5857
}
5958

6059
tool(tool: ChatTool) {
61-
if (!this.job.tools) {
62-
this.job.tools = [];
60+
if (!this.input.tools) {
61+
this.input.tools = [];
6362
}
64-
this.job.tools.push(tool.params);
63+
this.input.tools.push(tool.params);
6564
return this;
6665
}
6766

6867
toolChoice(toolChoice: string) {
69-
this.job.toolChoice = toolChoice;
68+
this.input.toolChoice = toolChoice;
7069
return this;
7170
}
7271

7372
responseFormat(responseFormat: ResponseFormat) {
74-
this.job.responseFormat = responseFormat;
73+
this.input.responseFormat = responseFormat;
7574
return this;
7675
}
7776

7877
jsonSchema(schema: z.ZodType, name: string, description?: string) {
79-
this.job.jsonSchema = {
78+
this.input.jsonSchema = {
8079
name,
8180
description,
8281
schema,
@@ -86,17 +85,10 @@ export class ChatJobBuilder extends JobBuilder {
8685
}
8786

8887
stream(streamOptions?: ChatStreamOptions) {
89-
this.job.stream = true;
88+
this.input.stream = true;
9089
if (streamOptions) {
91-
this.job.streamOptions = streamOptions;
90+
this.input.streamOptions = streamOptions;
9291
}
9392
return this;
9493
}
95-
96-
dump() {
97-
return {
98-
...super.dump(),
99-
...this.job,
100-
};
101-
}
10294
}

src/jobs/chat/schema.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,7 @@ export const ChatResultSchema = z.object({
8585
.optional(),
8686
});
8787

88-
export const ChatJobSchema = BaseJobSchema.extend({
89-
type: z.literal("chat"),
88+
export const ChatInputSchema = z.object({
9089
model: z.string(),
9190
temperature: z.number().optional(),
9291
stream: z.boolean().optional(),
@@ -100,6 +99,18 @@ export const ChatJobSchema = BaseJobSchema.extend({
10099
topK: z.number().optional(),
101100
systemPrompt: z.string().optional(),
102101
jsonSchema: JsonSchemaDefSchema.optional(),
102+
});
103103

104-
result: ChatResultSchema.optional(),
104+
export const ChatOutputSchema = z.object({
105+
raw: z.any(),
105106
});
107+
108+
export const ChatJobSchema = BaseJobSchema.extend({
109+
type: z.literal("chat"),
110+
input: ChatInputSchema,
111+
output: ChatOutputSchema.optional(),
112+
});
113+
114+
export type ChatInput = z.infer<typeof ChatInputSchema>;
115+
116+
export type ChatOutput = z.infer<typeof ChatOutputSchema>;

0 commit comments

Comments
 (0)