From 3f9036f4ffca123fd2d7eb222c78802dd534a277 Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Tue, 11 Jun 2024 18:58:15 -0400 Subject: [PATCH 1/3] fix client inference for non oai + check for usage for non oai and non readable --- bun.lockb | Bin 287174 -> 288360 bytes package.json | 6 ++--- src/instructor.ts | 57 +++++++++++++++++++++++++++++++++++++------ src/lib/index.ts | 42 +++++++++++++++++++++++++++++++ src/types/index.ts | 6 ++--- tests/stream.test.ts | 1 - 6 files changed, 98 insertions(+), 14 deletions(-) diff --git a/bun.lockb b/bun.lockb index d9d61e146237b2a4e6837ed26f6e6d52a7f2a947..5692ff0199c694285f196570aa1536e50311adb1 100755 GIT binary patch delta 41907 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 KCZwi&&i?~;a&klf diff --git a/package.json b/package.json index d358e689..372ab008 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "zod": ">=3.22.4" }, "devDependencies": { - "@anthropic-ai/sdk": "latest", + "@anthropic-ai/sdk": "0.22.0", "@changesets/changelog-github": "^0.5.0", "@changesets/cli": "^2.27.1", "@ianvs/prettier-plugin-sort-imports": "4.1.0", @@ -75,8 +75,8 @@ "eslint-plugin-only-warn": "^1.1.0", "eslint-plugin-prettier": "^5.1.2", "husky": "^8.0.3", - "llm-polyglot": "1.0.0", - "openai": "latest", + "llm-polyglot": "1.0.1", + "openai": "4.50.0", "prettier": "latest", "ts-inference-check": "^0.3.0", "tsup": "^8.0.1", diff --git a/src/instructor.ts b/src/instructor.ts index c6bd97ff..6b7313b0 100644 --- a/src/instructor.ts +++ b/src/instructor.ts @@ -22,11 +22,12 @@ import { PROVIDER_SUPPORTED_MODES_BY_MODEL, PROVIDERS } from "./constants/providers" +import { iterableTee } from "./lib" import { ClientTypeChatCompletionParams, CompletionMeta } from "./types" const MAX_RETRIES_DEFAULT = 0 -class Instructor { +class Instructor { readonly client: OpenAILikeClient readonly mode: Mode readonly provider: Provider @@ -46,7 +47,17 @@ class Instructor { logger = undefined, retryAllErrors = false }: InstructorConfig) { - this.client = client + if (!isGenericClient(client) && !(client instanceof OpenAI)) { + throw new Error("Client does not match the required structure") + } + + if (client instanceof OpenAI) { + this.client = client as OpenAI + } else { + this.client = client as C & GenericClient + } + + // this.client = client this.mode = mode this.debug = debug this.retryAllErrors = retryAllErrors @@ -308,7 +319,9 @@ class Instructor { debug: this.debug ?? false }) - async function checkForUsage(reader: Stream) { + async function checkForUsage( + reader: Stream | AsyncIterable + ) { for await (const chunk of reader) { if ("usage" in chunk) { streamUsage = chunk.usage as CompletionMeta["usage"] @@ -345,6 +358,24 @@ class Instructor { }) } + //check if async iterator + if ( + this.provider !== "OAI" && + completionParams?.stream && + completion?.[Symbol.asyncIterator] + ) { + const [completion1, completion2] = await iterableTee( + completion as AsyncIterable, + 2 + ) + + checkForUsage(completion1) + + return OAIStream({ + res: completion2 + }) + } + return OAIStream({ res: completion as unknown as AsyncIterable }) @@ -419,7 +450,7 @@ class Instructor { } } -export type InstructorClient = Instructor & OpenAILikeClient +export type InstructorClient = Instructor & OpenAILikeClient /** * Creates an instance of the `Instructor` class. @@ -442,9 +473,7 @@ export type InstructorClient = Instructor & * @param args * @returns */ -export default function createInstructor( - args: InstructorConfig -): InstructorClient { +export default function createInstructor(args: InstructorConfig): InstructorClient { const instructor = new Instructor(args) const instructorWithProxy = new Proxy(instructor, { get: (target, prop, receiver) => { @@ -458,3 +487,17 @@ export default function createInstructor( return instructorWithProxy as InstructorClient } +//eslint-disable-next-line @typescript-eslint/no-explicit-any +function isGenericClient(client: any): client is GenericClient { + return ( + typeof client === "object" && + client !== null && + "baseURL" in client && + "chat" in client && + typeof client.chat === "object" && + "completions" in client.chat && + typeof client.chat.completions === "object" && + "create" in client.chat.completions && + typeof client.chat.completions.create === "function" + ) +} diff --git a/src/lib/index.ts b/src/lib/index.ts index a164ae0c..540da954 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -7,3 +7,45 @@ export function omit(keys: K[], obj: T): Om } return result } + +export async function iterableTee( + iterable: AsyncIterable, + n: number +): Promise[]> { + const buffers: T[][] = Array.from({ length: n }, () => []) + const resolvers: (() => void)[] = [] + const iterator = iterable[Symbol.asyncIterator]() + let done = false + + async function* reader(index: number) { + while (true) { + if (buffers[index].length > 0) { + yield buffers[index].shift()! + } else if (done) { + break + } else { + await new Promise(resolve => resolvers.push(resolve)) + } + } + } + + ;(async () => { + for await (const item of { + [Symbol.asyncIterator]: () => iterator + }) { + for (const buffer of buffers) { + buffer.push(item) + } + + while (resolvers.length > 0) { + resolvers.shift()!() + } + } + done = true + while (resolvers.length > 0) { + resolvers.shift()!() + } + })() + + return Array.from({ length: n }, (_, i) => reader(i)) +} diff --git a/src/types/index.ts b/src/types/index.ts index d2f32108..717fc6bf 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -39,7 +39,7 @@ export type GenericClient = { baseURL?: string chat?: { completions?: { - create?: (params: GenericCreateParams) => Promise + create?:

(params: P) => Promise } } } @@ -55,7 +55,7 @@ export type ClientType = : C extends GenericClient ? "generic" : never -export type OpenAILikeClient = C extends OpenAI ? OpenAI : C & GenericClient +export type OpenAILikeClient = OpenAI | (C & GenericClient) export type SupportedInstructorClient = GenericClient | OpenAI export type LogLevel = "debug" | "info" | "warn" | "error" @@ -68,7 +68,7 @@ export type Mode = ZMode export type ResponseModel = ZResponseModel export interface InstructorConfig { - client: OpenAILikeClient + client: C mode: Mode debug?: boolean logger?: (level: LogLevel, ...args: T) => void diff --git a/tests/stream.test.ts b/tests/stream.test.ts index 79c40633..a14c3bc8 100644 --- a/tests/stream.test.ts +++ b/tests/stream.test.ts @@ -59,7 +59,6 @@ async function extractUser() { let extraction: Extraction = {} for await (const result of extractionStream) { - console.log(result) try { extraction = result expect(result).toHaveProperty("users") From 9621d595b5b4a0057c1f8020bcb022d895f063d4 Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Tue, 11 Jun 2024 19:07:26 -0400 Subject: [PATCH 2/3] changesets --- .changeset/light-chefs-clean.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/light-chefs-clean.md diff --git a/.changeset/light-chefs-clean.md b/.changeset/light-chefs-clean.md new file mode 100644 index 00000000..845ad9cf --- /dev/null +++ b/.changeset/light-chefs-clean.md @@ -0,0 +1,5 @@ +--- +"@instructor-ai/instructor": minor +--- + +update client types to better support non oai clients + updates to allow for passing usage properties into meta from non-oai clients From 5a12fbdab7e850d87717c55afc428d4b491ee5e4 Mon Sep 17 00:00:00 2001 From: Dimitri Kennedy Date: Wed, 12 Jun 2024 17:52:10 -0400 Subject: [PATCH 3/3] update anthropic tests and llm polyglot latest --- bun.lockb | Bin 288360 -> 287771 bytes package.json | 2 +- tests/anthropic.test.ts | 33 ++++++++++++++++++++------------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/bun.lockb b/bun.lockb index 5692ff0199c694285f196570aa1536e50311adb1..981b7ec2ae5ff199edc453a2bb0cdc39f7ebd61f 100755 GIT binary patch delta 3310 zcmb7`c~DhV9LLYQj|aSmqz@F)G#|Kcgt!2y3580zq~?;P7J}u5TZ>@XlK^oo?Ws3$ z87pVhNpp(wIqFzuQ&u`wQ!~b*;DV?%npkR)_Wk1bzy9jX{l4=(pYuESoO{mi-g$M$ zy_=4C*Ccd3u=PNjjfbZU|8dLA@##N=Z96&o+L{|1Ty0u^_uJCKb=UW<%nmUuXV*?> zXO;i*QC@XStGV;0&B>Z!jIY9&CdMqu&FR}1Q(Bha@@7m~UP5MXhZRUqPY&G5Y7!{A z(5EbAYDQt;(1ii69vG4qSe(+|JsU0ogRMY8O0w&Hv>polQ{3NO1(yVF0!KEdgjX8V zudz|kFWE7;EcIe^%bspbb{?y;P}ib%qP}!*mH(~F3htbX`F}%#8(TOA3>mR(ME+>c zu%VX%O9f+;7J&K0CK8HD>?9a+j~$FFW$857#uY zSNoFccdS1gmYj=KIn14=cO1r?F!uFk*7#uFBuDWl_BgLK%+B;$k@g-qN0oisYfZ3k z5loH(IAiaM0@xV^5E%_n6Py@r%}NbiO9%;84!6Et?eUfK;f?v}yj@dnrP&=Stle3d z$Z&6B*@H42F=QU7Qu{MQECQ@XY^E5F(v)*EQD%un!qk*J?1xY07C@dR$x5ZoQMY*5Ni)_>#){|bpZ2=tq0>S zc7)y#dq;7dz%s=)iggAX7UIV*N~vHM_~8oN1cu9Wg%ZWKD6SjWZOq2w->SIo@C`c0 zZHnswc313Ov7TUMV(rG@h+OowVAX8hOa2OTsh^pAMUYQ16Oimzu_xfY7|iVc4UD@r3OWJ9OunYL z(eMi~mWlkk*ckYHZU@SBu_xg*73{!8!~__kooYchc#{Qj)oG|X86R{iw1J%{p<>za2ek`f zVmV;ktw*46v1#z!2^KdPZ}U9#G?W2Ffcbf!7a%?%OA`&A4&M&v&aCAVF>Zz!6ZAf@ zneZdEn5JU0zy@P16SSGwZ1^-VCa6~|7xSBW0L;cH!8!B@Wa34O&4q6+)?AF^++Zv% z#OA{<)?#AB7JxC9iPuu>MfhIuoZrL>zJzA$Mu<HNo{Qr`dy6fF=b{VwSE7$#2>=6mlfGih#5kazSmS3B?aJRRJFMP{vtw(m zoVNUHR|TDh&Op@=|Jt2}&ILEtT7?eRdH4&#xH{`ur<;G7FG6*}q3E+W3As56Ky9%m? z&Om(mtNB8stSAot8R~3ixsnnR6B6wRx3je)G1$rN{3_N7WP3f%*kD+^^RsM+&$gF3 zFF8u>f)Zyd&#B^jH#oI4xV^-g;qZi)+yjN#!RyPM^@DWB%g3C9?bMu*c)Ow884;ZH Ojq{7r;4?WPk=DPqd$Lvl delta 3510 zcmbW3dr(!^8O8TKhbvqNdU=ST0lC!ZCB_@@1wMljqDErc6l+Vg2?8xhM6uc!la#0+ zn5Z$m#FLoVByFb|r;`|m=*{$zI6C9oX>99Y#0Wv2idr#^Nqu!KS^xFF?m3HZo!@?* zy}x@nZyk>5J|43*kiNa)?ZP*T%qG9T^5ojslyimeH*Gn3pt*Pa)ycPNSGLVKT^eRs z&cC)`xYcxK_v+RJ-@UkxG3KRZ%S$VZ%8gmnY|K5lUs^KZZri5Dsv*}CB05`B_k?vh za~jJ6v&Xqy!QB~I!S14aT=BuHfziR%Kt!W|aqjwHZ_!lC-yB@hG2LB`fpUUNv!{4= z!UZs-6|Bn6a<}4ca_~~^6wlDJ#*76w!K#T_o_yR*?7!QY-PqF^H)LW2*NP>35PK0V z#LI{_;#EYJ|Ba19yV?>a{9k=TlLot{K2kmUNZMy>_Ee7g;&|iWi^tyG<34h2Y~kwG zip~*#|FodK;Yib}+`oNYKdf-yKXy&O{Jeiwao%z>>rTgp8|Q{?p5VGP5X*9z+k(6_2uuI65_8nG%dWUDC?Tj8wb5GzqN05}eMLRD+PaG7|B^=`x$ z5V`un&?;7V4JZ|RSu6?c6?R~Bd}pn=>P@N|1{97err>5V z{>&o8wumKzO@>%r6-$AidY2fpRctu!9};^_EEV@TV!!TZ)y4;qCm2-2G~7QT)*$vh z+;egs?(1SB;2j;{HnID_s>K{I?(9fto!EA@8wEBytQvn&-V*e~&sD>>#nQp@#dd(< zGWSCnV(+NkXt3`v8&l$4wR-^mrq1@aYBvV#j@a+21@Wpeje@^d=Lf-(bXtD^V|50U z3KomFQ|&V0ePVwU!z;?%r@kM6(T;=sVjqfCj|U8>^DaTYL>FN;X68p?c*~hT!80>= zBXTiW&|kzpR=aGlePVkMahXZb0kIGw*T5V)Y?=Q3{{)b`IR!eVh8&m;nOMi+S^g?E z4gQ4MeTvBH>Coq5TmTsp@DvToengI!1DzH-U}1hf$qb0UJ^scHB9c7}bwW(KBVhcI z&4l(s!=Y9%TqYN)g?vz(7!!IPlm@kfabhO)Z}5~O5Ie+X@%c9aGHW{pXT#TkF>AZT z=D-(#F&VqX9)+I|#?m7;7d}_)f>=J-G_i|fkAaN^t7azm3UbBeSSmC5lGx+$OT;dV zeIG0aotfQNz_?pKfKI?Lk^9u{3HWExmx+8$?1%8raXV1H=K0eXK%AJ_{ckm#56_9o zz7hKo{0k5>{<_!#_)-n{t=Nyjn0zeXiTwnAFFX_ZKVpTFM;YWfolW&SG zgii)zCf^cU1n&l8Cf^3bWqt}pYCLWW*Yy+>t#&T4r@_vlLk`d10>ovCpsxrKIWPxY z3~|*n5X05E7@luCmI$#D_&;kGJYuC_+^v}q7scwILEIgdC@{W%%+H}hh*`^(vSAs- zr)C)_Rt`TL=RON@kk}G2Ca71e0)Czr6C?HvSRVQ^L1V?1Vt$hY$PA4Wtb|_HsQHx0w`vn;L7x4U(1XluN!m|t&TP066OzfBN zJd&po?-hF%{ybO_BJ+gvt%mpys2DK?j640D#A8S$Lax7vb5CPjkQ6ui$x9+>Oy$RdbMuV)gKBSPNx| zZ4_hsY_UYXI#F)+Ip^A~k=r_~l4O4DbwHg^7t{^$WA6fVF|@YBTJLi6`}|VK(`7wn zd-#oh1^QR0>Vg#&=HoYfGxQ4PsD$`Awh_nB03|@-&YPDl$K?r)xnk|IqWpZpq4W;0 zotAdX7kL)aVg<7Cg{^C)# z*M;`FZLj6d3}gf{onztlP?rgHhT8`dZGw{#c4FvIs{L89Q|YnGoRk{7%(cj=tFe1r zO-@y { }) }) -describe("LLMClient Anthropic Provider - mode: MD_JSON", () => { +describe("LLMClient Anthropic Provider - mode: TOOLS - stream", () => { const instructor = Instructor({ client: anthropicClient, - mode: "MD_JSON" + mode: "TOOLS" }) test("basic completion", async () => { const completion = await instructor.chat.completions.create({ model: "claude-3-sonnet-20240229", + stream: true, max_tokens: 1000, messages: [ { @@ -135,17 +136,24 @@ describe("LLMClient Anthropic Provider - mode: MD_JSON", () => { } ], response_model: { - name: "get_name", + name: "extract_name", schema: z.object({ name: z.string() }) } }) - expect(omit(["_meta"], completion)).toEqual({ name: "Dimitri Kennedy" }) + let final = {} + + for await (const result of completion) { + final = result + } + + //@ts-expect-error ignore for testing + expect(omit(["_meta"], final)).toEqual({ name: "Dimitri Kennedy" }) }) - test("complex schema - streaming", async () => { + test("complex schema", async () => { const completion = await instructor.chat.completions.create({ model: "claude-3-sonnet-20240229", max_tokens: 1000, @@ -173,14 +181,15 @@ describe("LLMClient Anthropic Provider - mode: MD_JSON", () => { Programming Leadership Communication - - ` } ], response_model: { name: "process_user_data", schema: z.object({ + story: z + .string() + .describe("A long and mostly made up story about the user - minimum 500 words"), userDetails: z.object({ firstName: z.string(), lastName: z.string(), @@ -196,21 +205,19 @@ describe("LLMClient Anthropic Provider - mode: MD_JSON", () => { years: z.number().optional() }) ), - skills: z.array(z.string()), - summaryOfWorldWarOne: z - .string() - .describe("A detailed summary of World War One and its major events - min 500 words") + skills: z.array(z.string()) }) } }) let final = {} + for await (const result of completion) { final = result } - //@ts-expect-error - lazy - expect(omit(["_meta", "summaryOfWorldWarOne"], final)).toEqual({ + //@ts-expect-error ignore for testing + expect(omit(["_meta", "story"], final)).toEqual({ userDetails: { firstName: "John", lastName: "Doe",