From 73878c602bd53cec4d9747b2314837e75f3d0e9c Mon Sep 17 00:00:00 2001 From: Travis Fischer Date: Fri, 26 Jul 2024 18:34:44 -0700 Subject: [PATCH] feat: add extractObject --- .../{extract-chain.ts => extract-user.ts} | 16 ++++++---- legacy/src/create-ai-chain.ts | 16 ++-------- legacy/src/create-ai-function.ts | 8 ++--- legacy/src/extract-object.ts | 9 ++++++ legacy/src/index.ts | 1 + legacy/src/types.ts | 32 ++++++++++++++++--- 6 files changed, 52 insertions(+), 30 deletions(-) rename legacy/examples/dexter/{extract-chain.ts => extract-user.ts} (53%) create mode 100644 legacy/src/extract-object.ts diff --git a/legacy/examples/dexter/extract-chain.ts b/legacy/examples/dexter/extract-user.ts similarity index 53% rename from legacy/examples/dexter/extract-chain.ts rename to legacy/examples/dexter/extract-user.ts index 4ac1349c..8729f046 100644 --- a/legacy/examples/dexter/extract-chain.ts +++ b/legacy/examples/dexter/extract-user.ts @@ -1,20 +1,25 @@ #!/usr/bin/env node import 'dotenv/config' -import { createAIChain, Msg } from '@agentic/stdlib' +import { extractObject, Msg } from '@agentic/stdlib' import { ChatModel } from '@dexaai/dexter' import { z } from 'zod' async function main() { const chatModel = new ChatModel({ - params: { model: 'gpt-4o', temperature: 0 }, + params: { model: 'gpt-4o-mini', temperature: 0 }, debug: true }) - const chain = createAIChain({ + const result = await extractObject({ chatFn: chatModel.run.bind(chatModel), params: { - messages: [Msg.system('Extract a JSON user object from the given text.')] + messages: [ + Msg.system('Extract a JSON user object from the given text.'), + Msg.user( + 'Bob Vance is 42 years old and lives in Brooklyn, NY. He is a software engineer.' + ) + ] }, schema: z.object({ name: z.string(), @@ -23,9 +28,6 @@ async function main() { }) }) - const result = await chain( - 'Bob Vance is 42 years old and lives in Brooklyn, NY. He is a software engineer.' - ) console.log(result) } diff --git a/legacy/src/create-ai-chain.ts b/legacy/src/create-ai-chain.ts index 3ed7d699..cf31d98d 100644 --- a/legacy/src/create-ai-chain.ts +++ b/legacy/src/create-ai-chain.ts @@ -1,5 +1,4 @@ import type { SetOptional } from 'type-fest' -import type { ZodType } from 'zod' import pMap from 'p-map' import type * as types from './types.js' @@ -33,18 +32,7 @@ export function createAIChain({ maxRetries = 2, toolCallConcurrency = 8, injectSchemaIntoSystemMessage = true -}: { - chatFn: types.ChatFn - params?: types.Simplify< - Partial> - > - tools?: types.AIFunctionLike[] - schema?: ZodType | types.Schema - maxCalls?: number - maxRetries?: number - toolCallConcurrency?: number - injectSchemaIntoSystemMessage?: boolean -}): types.AIChain { +}: types.AIChainParams): types.AIChain { const functionSet = new AIFunctionSet(tools) const defaultParams: Partial | undefined = rawSchema && !functionSet.size @@ -67,7 +55,7 @@ export function createAIChain({ ...chatParams, messages: [ ...(params?.messages ?? []), - ...(chatParams.messages ?? []) + ...(chatParams?.messages ?? []) ] } diff --git a/legacy/src/create-ai-function.ts b/legacy/src/create-ai-function.ts index c2988829..ea620f9d 100644 --- a/legacy/src/create-ai-function.ts +++ b/legacy/src/create-ai-function.ts @@ -14,7 +14,7 @@ import { zodToJsonSchema } from './zod-to-json-schema.js' * The `spec` property of the returned function is the spec for adding the * function to the OpenAI API `functions` property. */ -export function createAIFunction, Return>( +export function createAIFunction, Output>( spec: { /** Name of the function. */ name: string @@ -24,8 +24,8 @@ export function createAIFunction, Return>( inputSchema: InputSchema }, /** Implementation of the function to call with the parsed arguments. */ - implementation: (params: z.infer) => types.MaybePromise -): types.AIFunction { + implementation: (params: z.infer) => types.MaybePromise +): types.AIFunction { assert(spec.name, 'createAIFunction missing required "spec.name"') assert( spec.inputSchema, @@ -52,7 +52,7 @@ export function createAIFunction, Return>( } // Call the implementation function with the parsed arguments. - const aiFunction: types.AIFunction = ( + const aiFunction: types.AIFunction = ( input: string | types.Msg ) => { const parsedInput = parseInput(input) diff --git a/legacy/src/extract-object.ts b/legacy/src/extract-object.ts new file mode 100644 index 00000000..458cc643 --- /dev/null +++ b/legacy/src/extract-object.ts @@ -0,0 +1,9 @@ +import type * as types from './types.js' +import { createAIChain } from './create-ai-chain.js' + +export function extractObject( + args: types.ExtractObjectParams +): Promise { + const chain = createAIChain(args) + return chain() +} diff --git a/legacy/src/index.ts b/legacy/src/index.ts index c4984bc8..4f0b4346 100644 --- a/legacy/src/index.ts +++ b/legacy/src/index.ts @@ -2,6 +2,7 @@ export * from './ai-function-set.js' export * from './create-ai-chain.js' export * from './create-ai-function.js' export * from './errors.js' +export * from './extract-object.js' export * from './fns.js' export * from './message.js' export * from './parse-structured-output.js' diff --git a/legacy/src/types.ts b/legacy/src/types.ts index ec19eeda..48a30308 100644 --- a/legacy/src/types.ts +++ b/legacy/src/types.ts @@ -1,9 +1,10 @@ -import type { Jsonifiable, SetOptional, Simplify } from 'type-fest' +import type { Jsonifiable, SetOptional, SetRequired, Simplify } from 'type-fest' import type { z } from 'zod' import type { AIFunctionSet } from './ai-function-set.js' import type { AIFunctionsProvider } from './fns.js' import type { Msg } from './message.js' +import type { Schema } from './schema.js' export type { Msg } from './message.js' export type { Schema } from './schema.js' @@ -65,14 +66,14 @@ export type AIFunctionLike = AIFunctionsProvider | AIFunction | AIFunctionSet */ export interface AIFunction< InputSchema extends z.ZodObject = z.ZodObject, - Return = any + Output = any > { /** * Invokes the underlying AI function `impl` but first validates the input * against this function's `inputSchema`. This method is callable and is * meant to be passed the raw LLM JSON string or an OpenAI-compatible Message. */ - (input: string | Msg): MaybePromise + (input: string | Msg): MaybePromise /** The Zod schema for the input object. */ inputSchema: InputSchema @@ -87,7 +88,7 @@ export interface AIFunction< * The underlying function implementation without any arg parsing or validation. */ // TODO: this `any` shouldn't be necessary, but it is for `createAIFunction` results to be assignable to `AIFunctionLike` - impl: (params: z.infer | any) => MaybePromise + impl: (params: z.infer | any) => MaybePromise } export interface ChatParams { @@ -124,7 +125,7 @@ export type ChatFn = ( export type AIChainResult = string | Record export type AIChain = ( - params: + params?: | string | Simplify, 'model'>> ) => Promise @@ -140,3 +141,24 @@ export type SafeParseResult = } export type ValidatorFn = (value: unknown) => SafeParseResult + +export type AIChainParams = { + chatFn: ChatFn + params?: Simplify>> + tools?: AIFunctionLike[] + schema?: z.ZodType | Schema + maxCalls?: number + maxRetries?: number + toolCallConcurrency?: number + injectSchemaIntoSystemMessage?: boolean +} + +export type ExtractObjectParams = + Simplify< + SetRequired< + Omit, 'tools' | 'toolCallConcurrency' | 'params'>, + 'schema' + > & { + params: SetRequired, 'messages'> + } + >