kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat: add support for JSON Schema in AIFunction inputSchema in addition to zod schemas
rodzic
a9e0389bf3
commit
2db62b0ca2
|
@ -56,11 +56,13 @@
|
|||
"group": "Tools",
|
||||
"pages": [
|
||||
"tools/apollo",
|
||||
"tools/arxiv",
|
||||
"tools/bing",
|
||||
"tools/calculator",
|
||||
"tools/clearbit",
|
||||
"tools/dexa",
|
||||
"tools/diffbot",
|
||||
"tools/duck-duck-go",
|
||||
"tools/e2b",
|
||||
"tools/exa",
|
||||
"tools/firecrawl",
|
||||
|
@ -70,6 +72,7 @@
|
|||
"tools/jina",
|
||||
"tools/leadmagic",
|
||||
"tools/midjourney",
|
||||
"tools/mcp",
|
||||
"tools/novu",
|
||||
"tools/people-data-labs",
|
||||
"tools/perigon",
|
||||
|
|
|
@ -9,9 +9,11 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@agentic/ai-sdk": "workspace:*",
|
||||
"@agentic/mcp": "workspace:*",
|
||||
"@agentic/weather": "workspace:*",
|
||||
"@ai-sdk/openai": "catalog:",
|
||||
"ai": "catalog:",
|
||||
"exit-hook": "^4.0.0",
|
||||
"openai": "catalog:",
|
||||
"zod": "catalog:"
|
||||
},
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
import { type AIFunctionLike, AIFunctionSet } from '@agentic/core'
|
||||
import { tool } from 'ai'
|
||||
import {
|
||||
type AIFunctionLike,
|
||||
AIFunctionSet,
|
||||
asSchema,
|
||||
isZodSchema
|
||||
} from '@agentic/core'
|
||||
import { jsonSchema, tool } from 'ai'
|
||||
|
||||
/**
|
||||
* Converts a set of Agentic stdlib AI functions to an object compatible with
|
||||
|
@ -13,7 +18,9 @@ export function createAISDKTools(...aiFunctionLikeTools: AIFunctionLike[]) {
|
|||
fn.spec.name,
|
||||
tool({
|
||||
description: fn.spec.description,
|
||||
parameters: fn.inputSchema,
|
||||
parameters: isZodSchema(fn.inputSchema)
|
||||
? fn.inputSchema
|
||||
: jsonSchema(asSchema(fn.inputSchema).jsonSchema),
|
||||
execute: fn.execute
|
||||
})
|
||||
])
|
||||
|
|
|
@ -4,7 +4,9 @@ import { z } from 'zod'
|
|||
import { createAIFunction } from './create-ai-function'
|
||||
import { type Msg } from './message'
|
||||
|
||||
const fullName = createAIFunction(
|
||||
// TODO: Add tests for passing JSON schema directly.
|
||||
|
||||
const fullNameAIFunction = createAIFunction(
|
||||
{
|
||||
name: 'fullName',
|
||||
description: 'Returns the full name of a person.',
|
||||
|
@ -20,11 +22,11 @@ const fullName = createAIFunction(
|
|||
|
||||
describe('createAIFunction()', () => {
|
||||
test('exposes OpenAI function calling spec', () => {
|
||||
expect(fullName.spec.name).toEqual('fullName')
|
||||
expect(fullName.spec.description).toEqual(
|
||||
expect(fullNameAIFunction.spec.name).toEqual('fullName')
|
||||
expect(fullNameAIFunction.spec.description).toEqual(
|
||||
'Returns the full name of a person.'
|
||||
)
|
||||
expect(fullName.spec.parameters).toEqual({
|
||||
expect(fullNameAIFunction.spec.parameters).toEqual({
|
||||
properties: {
|
||||
first: { type: 'string' },
|
||||
last: { type: 'string' }
|
||||
|
@ -36,9 +38,9 @@ describe('createAIFunction()', () => {
|
|||
})
|
||||
|
||||
test('executes the function with JSON string', async () => {
|
||||
expect(await fullName('{"first": "John", "last": "Doe"}')).toEqual(
|
||||
'John Doe'
|
||||
)
|
||||
expect(
|
||||
await fullNameAIFunction('{"first": "John", "last": "Doe"}')
|
||||
).toEqual('John Doe')
|
||||
})
|
||||
|
||||
test('executes the function with OpenAI Message', async () => {
|
||||
|
@ -51,6 +53,6 @@ describe('createAIFunction()', () => {
|
|||
}
|
||||
}
|
||||
|
||||
expect(await fullName(message)).toEqual('Jane Smith')
|
||||
expect(await fullNameAIFunction(message)).toEqual('Jane Smith')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
import type { z } from 'zod'
|
||||
|
||||
import type * as types from './types'
|
||||
import { parseStructuredOutput } from './parse-structured-output'
|
||||
import { asSchema } from './schema'
|
||||
import { assert } from './utils'
|
||||
import { zodToJsonSchema } from './zod-to-json-schema'
|
||||
|
||||
/**
|
||||
* Create a function meant to be used with OpenAI tool or function calling.
|
||||
|
@ -14,7 +11,10 @@ import { zodToJsonSchema } from './zod-to-json-schema'
|
|||
* The `spec` property of the returned function is the spec for adding the
|
||||
* function to the OpenAI API `functions` property.
|
||||
*/
|
||||
export function createAIFunction<InputSchema extends z.ZodObject<any>, Output>(
|
||||
export function createAIFunction<
|
||||
InputSchema extends types.AIFunctionInputSchema,
|
||||
Output
|
||||
>(
|
||||
spec: {
|
||||
/** Name of the function. */
|
||||
name: string
|
||||
|
@ -29,7 +29,9 @@ export function createAIFunction<InputSchema extends z.ZodObject<any>, Output>(
|
|||
strict?: boolean
|
||||
},
|
||||
/** Implementation of the function to call with the parsed arguments. */
|
||||
implementation: (params: z.infer<InputSchema>) => types.MaybePromise<Output>
|
||||
implementation: (
|
||||
params: types.inferInput<InputSchema>
|
||||
) => types.MaybePromise<Output>
|
||||
): types.AIFunction<InputSchema, Output> {
|
||||
assert(spec.name, 'createAIFunction missing required "spec.name"')
|
||||
assert(
|
||||
|
@ -42,17 +44,22 @@ export function createAIFunction<InputSchema extends z.ZodObject<any>, Output>(
|
|||
'createAIFunction "implementation" must be a function'
|
||||
)
|
||||
|
||||
const strict = !!spec.strict
|
||||
const inputSchema = asSchema(spec.inputSchema, { strict })
|
||||
|
||||
/** Parse the arguments string, optionally reading from a message. */
|
||||
const parseInput = (input: string | types.Msg) => {
|
||||
const parseInput = (
|
||||
input: string | types.Msg
|
||||
): types.inferInput<InputSchema> => {
|
||||
if (typeof input === 'string') {
|
||||
return parseStructuredOutput(input, spec.inputSchema)
|
||||
return inputSchema.parse(input)
|
||||
} else {
|
||||
const args = input.function_call?.arguments
|
||||
assert(
|
||||
args,
|
||||
`Missing required function_call.arguments for function ${spec.name}`
|
||||
)
|
||||
return parseStructuredOutput(args, spec.inputSchema)
|
||||
return inputSchema.parse(args)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,19 +78,19 @@ export function createAIFunction<InputSchema extends z.ZodObject<any>, Output>(
|
|||
writable: false
|
||||
})
|
||||
|
||||
const strict = !!spec.strict
|
||||
|
||||
aiFunction.inputSchema = spec.inputSchema
|
||||
aiFunction.parseInput = parseInput
|
||||
|
||||
aiFunction.spec = {
|
||||
name: spec.name,
|
||||
description: spec.description?.trim() ?? '',
|
||||
parameters: zodToJsonSchema(spec.inputSchema, { strict }),
|
||||
parameters: inputSchema.jsonSchema,
|
||||
type: 'function',
|
||||
strict
|
||||
}
|
||||
|
||||
aiFunction.execute = (
|
||||
params: z.infer<InputSchema>
|
||||
params: types.inferInput<InputSchema>
|
||||
): types.MaybePromise<Output> => {
|
||||
return implementation(params)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import type { z } from 'zod'
|
||||
|
||||
import type * as types from './types'
|
||||
import { AIFunctionSet } from './ai-function-set'
|
||||
import { createAIFunction } from './create-ai-function'
|
||||
|
@ -8,7 +6,7 @@ import { assert } from './utils'
|
|||
export interface PrivateAIFunctionMetadata {
|
||||
name: string
|
||||
description: string
|
||||
inputSchema: z.AnyZodObject
|
||||
inputSchema: types.AIFunctionInputSchema
|
||||
methodName: string
|
||||
strict?: boolean
|
||||
}
|
||||
|
@ -35,7 +33,7 @@ if (typeof Symbol === 'function' && Symbol.metadata) {
|
|||
}
|
||||
|
||||
export abstract class AIFunctionsProvider {
|
||||
private _functions?: AIFunctionSet
|
||||
protected _functions?: AIFunctionSet
|
||||
|
||||
/**
|
||||
* An `AIFunctionSet` containing all of the AI-compatible functions exposed
|
||||
|
@ -70,7 +68,7 @@ export abstract class AIFunctionsProvider {
|
|||
|
||||
export function aiFunction<
|
||||
This extends AIFunctionsProvider,
|
||||
InputSchema extends z.SomeZodObject,
|
||||
InputSchema extends types.AIFunctionInputSchema,
|
||||
OptionalArgs extends Array<undefined>,
|
||||
Return extends types.MaybePromise<any>
|
||||
>({
|
||||
|
@ -87,14 +85,14 @@ export function aiFunction<
|
|||
return (
|
||||
_targetMethod: (
|
||||
this: This,
|
||||
input: z.infer<InputSchema>,
|
||||
input: types.inferInput<InputSchema>,
|
||||
...optionalArgs: OptionalArgs
|
||||
) => Return,
|
||||
context: ClassMethodDecoratorContext<
|
||||
This,
|
||||
(
|
||||
this: This,
|
||||
input: z.infer<InputSchema>,
|
||||
input: types.inferInput<InputSchema>,
|
||||
...optionalArgs: OptionalArgs
|
||||
) => Return
|
||||
>
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import { expect, test } from 'vitest'
|
||||
import { z } from 'zod'
|
||||
|
||||
import { asSchema, createJsonSchema, isZodSchema } from './schema'
|
||||
|
||||
test('isZodSchema', () => {
|
||||
expect(isZodSchema(z.object({}))).toBe(true)
|
||||
expect(isZodSchema({})).toBe(false)
|
||||
})
|
||||
|
||||
test('asSchema', () => {
|
||||
expect(asSchema(z.object({})).jsonSchema).toEqual({
|
||||
type: 'object',
|
||||
properties: {},
|
||||
additionalProperties: false
|
||||
})
|
||||
expect(asSchema(createJsonSchema({})).jsonSchema).toEqual({})
|
||||
})
|
|
@ -39,6 +39,11 @@ export type Schema<TData = unknown> = {
|
|||
* Schema type for inference.
|
||||
*/
|
||||
_type: TData
|
||||
|
||||
/**
|
||||
* Source Zod schema if this object was created from a Zod schema.
|
||||
*/
|
||||
_source?: any
|
||||
}
|
||||
|
||||
export function isSchema(value: unknown): value is Schema {
|
||||
|
@ -56,10 +61,8 @@ export function isZodSchema(value: unknown): value is z.ZodType {
|
|||
return (
|
||||
typeof value === 'object' &&
|
||||
value !== null &&
|
||||
'_type' in value &&
|
||||
'_output' in value &&
|
||||
'_input' in value &&
|
||||
'_def' in value &&
|
||||
'~standard' in value &&
|
||||
'parse' in value &&
|
||||
'safeParse' in value
|
||||
)
|
||||
|
@ -73,16 +76,25 @@ export function asSchema<TData>(
|
|||
}
|
||||
|
||||
/**
|
||||
* Create a schema from a JSON Schema.
|
||||
* Create a Schema from a JSON Schema.
|
||||
*
|
||||
* All `AIFunction` input schemas accept either a Zod schema or a custom JSON
|
||||
* Schema. Use this function to wrap JSON schemas for use with `AIFunction`.
|
||||
*
|
||||
* Note that JSON Schemas are not validated by default, so you have to pass
|
||||
* in an optional `parse` function (using `ajv`, for instance) if you'd like to
|
||||
* validate them at runtime.
|
||||
*/
|
||||
export function createSchema<TData = unknown>(
|
||||
export function createJsonSchema<TData = unknown>(
|
||||
jsonSchema: types.JSONSchema,
|
||||
{
|
||||
parse = (value) => value as TData,
|
||||
safeParse
|
||||
safeParse,
|
||||
source
|
||||
}: {
|
||||
parse?: types.ParseFn<TData>
|
||||
safeParse?: types.SafeParseFn<TData>
|
||||
source?: any
|
||||
} = {}
|
||||
): Schema<TData> {
|
||||
safeParse ??= (value: unknown) => {
|
||||
|
@ -99,7 +111,8 @@ export function createSchema<TData = unknown>(
|
|||
_type: undefined as TData,
|
||||
jsonSchema,
|
||||
parse,
|
||||
safeParse
|
||||
safeParse,
|
||||
_source: source
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,10 +120,11 @@ export function createSchemaFromZodSchema<TData>(
|
|||
zodSchema: z.Schema<TData>,
|
||||
opts: { strict?: boolean } = {}
|
||||
): Schema<TData> {
|
||||
return createSchema(zodToJsonSchema(zodSchema, opts), {
|
||||
return createJsonSchema(zodToJsonSchema(zodSchema, opts), {
|
||||
parse: (value) => {
|
||||
return parseStructuredOutput(value, zodSchema)
|
||||
}
|
||||
},
|
||||
source: zodSchema
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import type { z } from 'zod'
|
|||
import type { AIFunctionSet } from './ai-function-set'
|
||||
import type { AIFunctionsProvider } from './fns'
|
||||
import type { Msg } from './message'
|
||||
import type { Schema } from './schema'
|
||||
|
||||
export type { Msg } from './message'
|
||||
export type { Schema } from './schema'
|
||||
|
@ -52,6 +53,20 @@ export interface AIToolSpec {
|
|||
function: AIFunctionSpec
|
||||
}
|
||||
|
||||
/**
|
||||
* A Zod object schema or a custom schema created from a JSON schema via
|
||||
* `createSchema()`.
|
||||
*/
|
||||
export type AIFunctionInputSchema = z.ZodObject<any> | Schema<any>
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
export type inferInput<InputSchema extends AIFunctionInputSchema> =
|
||||
InputSchema extends Schema<any>
|
||||
? InputSchema['_type']
|
||||
: InputSchema extends z.ZodTypeAny
|
||||
? z.infer<InputSchema>
|
||||
: never
|
||||
|
||||
/** The implementation of the function, with arg parsing and validation. */
|
||||
export type AIFunctionImpl<Return> = Omit<
|
||||
(input: string | Msg) => MaybePromise<Return>,
|
||||
|
@ -65,13 +80,18 @@ export type AIFunctionImpl<Return> = Omit<
|
|||
* via the `.functions` property
|
||||
* - `AIFunction` - Individual functions
|
||||
*/
|
||||
export type AIFunctionLike = AIFunctionsProvider | AIFunction | AIFunctionSet
|
||||
export type AIFunctionLike =
|
||||
| AIFunctionsProvider
|
||||
| AIFunction<AIFunctionInputSchema>
|
||||
| AIFunctionSet
|
||||
|
||||
/**
|
||||
* A function meant to be used with LLM function calling.
|
||||
*/
|
||||
export interface AIFunction<
|
||||
InputSchema extends z.ZodObject<any> = z.ZodObject<any>,
|
||||
// TODO
|
||||
// InputSchema extends AIFunctionInputSchema = z.ZodObject<any>,
|
||||
InputSchema extends AIFunctionInputSchema = AIFunctionInputSchema,
|
||||
Output = any
|
||||
> {
|
||||
/**
|
||||
|
@ -81,11 +101,11 @@ export interface AIFunction<
|
|||
*/
|
||||
(input: string | Msg): MaybePromise<Output>
|
||||
|
||||
/** The Zod schema for the input object. */
|
||||
/** The schema for the input object (zod or custom schema). */
|
||||
inputSchema: InputSchema
|
||||
|
||||
/** Parse the function arguments from a message. */
|
||||
parseInput(input: string | Msg): z.infer<InputSchema>
|
||||
parseInput(input: string | Msg): inferInput<InputSchema>
|
||||
|
||||
/** The JSON schema function spec for the OpenAI API `functions` property. */
|
||||
spec: AIFunctionSpec
|
||||
|
@ -94,7 +114,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`
|
||||
execute: (params: z.infer<InputSchema> | any) => MaybePromise<Output>
|
||||
execute: (params: inferInput<InputSchema> | any) => MaybePromise<Output>
|
||||
}
|
||||
|
||||
export type SafeParseResult<TData> =
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { type AIFunctionLike, AIFunctionSet } from '@agentic/core'
|
||||
import { type AIFunctionLike, AIFunctionSet, isZodSchema } from '@agentic/core'
|
||||
import { createAIFunction } from '@dexaai/dexter'
|
||||
|
||||
/**
|
||||
|
@ -10,8 +10,14 @@ export function createDexterFunctions(
|
|||
) {
|
||||
const fns = new AIFunctionSet(aiFunctionLikeTools)
|
||||
|
||||
return fns.map((fn) =>
|
||||
createAIFunction(
|
||||
return fns.map((fn) => {
|
||||
if (!isZodSchema(fn.inputSchema)) {
|
||||
throw new Error(
|
||||
`Dexter tools only support Zod schemas: ${fn.spec.name} tool uses a custom JSON Schema, which is currently not supported.`
|
||||
)
|
||||
}
|
||||
|
||||
return createAIFunction(
|
||||
{
|
||||
name: fn.spec.name,
|
||||
description: fn.spec.description,
|
||||
|
@ -19,5 +25,5 @@ export function createDexterFunctions(
|
|||
},
|
||||
fn.execute
|
||||
)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
import type { Genkit } from 'genkit'
|
||||
import { type AIFunctionLike, AIFunctionSet } from '@agentic/core'
|
||||
import {
|
||||
type AIFunctionLike,
|
||||
AIFunctionSet,
|
||||
asSchema,
|
||||
isZodSchema
|
||||
} from '@agentic/core'
|
||||
import { z } from 'zod'
|
||||
|
||||
/**
|
||||
|
@ -12,15 +17,22 @@ export function createGenkitTools(
|
|||
) {
|
||||
const fns = new AIFunctionSet(aiFunctionLikeTools)
|
||||
|
||||
return fns.map((fn) =>
|
||||
genkit.defineTool(
|
||||
return fns.map((fn) => {
|
||||
const inputSchemaKey = isZodSchema(fn.inputSchema)
|
||||
? ('inputSchema' as const)
|
||||
: ('inputJsonSchema' as const)
|
||||
|
||||
return genkit.defineTool(
|
||||
{
|
||||
name: fn.spec.name,
|
||||
description: fn.spec.description,
|
||||
inputSchema: fn.inputSchema,
|
||||
// TODO: This schema handling should be able to be cleaned up.
|
||||
[inputSchemaKey]: isZodSchema(fn.inputSchema)
|
||||
? fn.inputSchema
|
||||
: asSchema(fn.inputSchema).jsonSchema,
|
||||
outputSchema: z.any()
|
||||
},
|
||||
fn.execute
|
||||
)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { type AIFunctionLike, AIFunctionSet } from '@agentic/core'
|
||||
import { type AIFunctionLike, AIFunctionSet, isZodSchema } from '@agentic/core'
|
||||
import { createTool } from '@mastra/core/tools'
|
||||
|
||||
/**
|
||||
|
@ -9,14 +9,22 @@ export function createMastraTools(...aiFunctionLikeTools: AIFunctionLike[]) {
|
|||
const fns = new AIFunctionSet(aiFunctionLikeTools)
|
||||
|
||||
return Object.fromEntries(
|
||||
fns.map((fn) => [
|
||||
fn.spec.name,
|
||||
createTool({
|
||||
id: fn.spec.name,
|
||||
description: fn.spec.description,
|
||||
inputSchema: fn.inputSchema,
|
||||
execute: (ctx) => fn.execute(ctx.context)
|
||||
})
|
||||
])
|
||||
fns.map((fn) => {
|
||||
if (!isZodSchema(fn.inputSchema)) {
|
||||
throw new Error(
|
||||
`Mastra tools only support Zod schemas: ${fn.spec.name} tool uses a custom JSON Schema, which is currently not supported.`
|
||||
)
|
||||
}
|
||||
|
||||
return [
|
||||
fn.spec.name,
|
||||
createTool({
|
||||
id: fn.spec.name,
|
||||
description: fn.spec.description,
|
||||
inputSchema: fn.inputSchema,
|
||||
execute: (ctx) => fn.execute(ctx.context)
|
||||
})
|
||||
]
|
||||
})
|
||||
)
|
||||
}
|
||||
|
|
|
@ -32,12 +32,14 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@agentic/apollo": "workspace:*",
|
||||
"@agentic/arxiv": "workspace:*",
|
||||
"@agentic/bing": "workspace:*",
|
||||
"@agentic/calculator": "workspace:*",
|
||||
"@agentic/clearbit": "workspace:*",
|
||||
"@agentic/core": "workspace:*",
|
||||
"@agentic/dexa": "workspace:*",
|
||||
"@agentic/diffbot": "workspace:*",
|
||||
"@agentic/duck-duck-go": "workspace:*",
|
||||
"@agentic/e2b": "workspace:*",
|
||||
"@agentic/exa": "workspace:*",
|
||||
"@agentic/firecrawl": "workspace:*",
|
||||
|
@ -48,6 +50,7 @@
|
|||
"@agentic/jina": "workspace:*",
|
||||
"@agentic/leadmagic": "workspace:*",
|
||||
"@agentic/midjourney": "workspace:*",
|
||||
"@agentic/mcp": "workspace:*",
|
||||
"@agentic/novu": "workspace:*",
|
||||
"@agentic/people-data-labs": "workspace:*",
|
||||
"@agentic/perigon": "workspace:*",
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
export * from '@agentic/apollo'
|
||||
export * from '@agentic/arxiv'
|
||||
export * from '@agentic/bing'
|
||||
export * from '@agentic/calculator'
|
||||
export * from '@agentic/clearbit'
|
||||
export * from '@agentic/dexa'
|
||||
export * from '@agentic/diffbot'
|
||||
export * from '@agentic/duck-duck-go'
|
||||
export * from '@agentic/e2b'
|
||||
export * from '@agentic/exa'
|
||||
export * from '@agentic/firecrawl'
|
||||
|
@ -13,6 +15,7 @@ export * from '@agentic/hacker-news'
|
|||
export * from '@agentic/hunter'
|
||||
export * from '@agentic/jina'
|
||||
export * from '@agentic/leadmagic'
|
||||
export * from '@agentic/mcp'
|
||||
export * from '@agentic/midjourney'
|
||||
export * from '@agentic/novu'
|
||||
export * from '@agentic/people-data-labs'
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { type AIFunctionLike, AIFunctionSet } from '@agentic/core'
|
||||
import { type AIFunctionLike, AIFunctionSet, isZodSchema } from '@agentic/core'
|
||||
import { tool, type ToolResult } from '@xsai/tool'
|
||||
|
||||
/**
|
||||
|
@ -11,13 +11,19 @@ export function createXSAITools(
|
|||
const fns = new AIFunctionSet(aiFunctionLikeTools)
|
||||
|
||||
return Promise.all(
|
||||
fns.map((fn) =>
|
||||
tool({
|
||||
fns.map((fn) => {
|
||||
if (!isZodSchema(fn.inputSchema)) {
|
||||
throw new Error(
|
||||
`xsAI tools only support Standard schemas like Zod: ${fn.spec.name} tool uses a custom JSON Schema, which is currently not supported.`
|
||||
)
|
||||
}
|
||||
|
||||
return tool({
|
||||
name: fn.spec.name,
|
||||
description: fn.spec.description,
|
||||
parameters: fn.inputSchema,
|
||||
execute: fn.execute
|
||||
})
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
|
507
pnpm-lock.yaml
507
pnpm-lock.yaml
Plik diff jest za duży
Load Diff
|
@ -23,6 +23,8 @@ catalog:
|
|||
type-fest: ^4.37.0
|
||||
wikibase-sdk: ^10.2.2
|
||||
'@types/jsrsasign': ^10.5.15
|
||||
fast-xml-parser: ^5.0.9
|
||||
'@modelcontextprotocol/sdk': ^1.7.0
|
||||
|
||||
# vercel ai sdk
|
||||
ai: ^4.1.61
|
||||
|
|
|
@ -133,11 +133,13 @@ Full docs are available at [agentic.so](https://agentic.so).
|
|||
| Service / Tool | Package | Docs | Description |
|
||||
| ------------------------------------------------------------------------ | --------------------------- | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [Apollo](https://docs.apollo.io) | `@agentic/apollo` | [docs](https://agentic.so/tools/apollo) | B2B person and company enrichment API. |
|
||||
| [ArXiv](https://arxiv.org) | `@agentic/arxiv` | [docs](https://agentic.so/tools/arxiv) | Search for research articles. |
|
||||
| [Bing](https://www.microsoft.com/en-us/bing/apis/bing-web-search-api) | `@agentic/bing` | [docs](https://agentic.so/tools/bing) | Bing web search. |
|
||||
| [Calculator](https://github.com/josdejong/mathjs) | `@agentic/calculator` | [docs](https://agentic.so/tools/calculator) | Basic calculator for simple mathematical expressions. |
|
||||
| [Clearbit](https://dashboard.clearbit.com/docs) | `@agentic/clearbit` | [docs](https://agentic.so/tools/clearbit) | Resolving and enriching people and company data. |
|
||||
| [Dexa](https://dexa.ai) | `@agentic/dexa` | [docs](https://agentic.so/tools/dexa) | Answers questions from the world's best podcasters. |
|
||||
| [Diffbot](https://docs.diffbot.com) | `@agentic/diffbot` | [docs](https://agentic.so/tools/diffbot) | Web page classification and scraping; person and company data enrichment. |
|
||||
| [DuckDuckGo](https://duckduckgo.com) | `@agentic/duck-duck-go` | [docs](https://agentic.so/tools/duck-duck-go) | Privacy-focused web search API. |
|
||||
| [E2B](https://e2b.dev) | `@agentic/e2b` | [docs](https://agentic.so/tools/e2b) | Hosted Python code interpreter sandbox which is really useful for data analysis, flexible code execution, and advanced reasoning on-the-fly. |
|
||||
| [Exa](https://docs.exa.ai) | `@agentic/exa` | [docs](https://agentic.so/tools/exa) | Web search tailored for LLMs. |
|
||||
| [Firecrawl](https://www.firecrawl.dev) | `@agentic/firecrawl` | [docs](https://agentic.so/tools/firecrawl) | Website scraping and structured data extraction. |
|
||||
|
@ -147,6 +149,7 @@ Full docs are available at [agentic.so](https://agentic.so).
|
|||
| [Jina](https://jina.ai/reader) | `@agentic/jina` | [docs](https://agentic.so/tools/jina) | URL scraper and web search. |
|
||||
| [LeadMagic](https://leadmagic.io) | `@agentic/leadmagic` | [docs](https://agentic.so/tools/leadmagic) | B2B person, company, and email enrichment API. |
|
||||
| [Midjourney](https://www.imagineapi.dev) | `@agentic/midjourney` | [docs](https://agentic.so/tools/midjourney) | Unofficial Midjourney client for generative images. |
|
||||
| [McpTools](https://modelcontextprotocol.io) | `@agentic/mcp` | [docs](https://agentic.so/tools/mcp) | Model Context Protocol (MCP) adapter, supporting any MCP server. Use [createMcpTools](https://agentic.so/tools/mcp) to spawn or connect to an MCP server. |
|
||||
| [Novu](https://novu.co) | `@agentic/novu` | [docs](https://agentic.so/tools/novu) | Sending notifications (email, SMS, in-app, push, etc). |
|
||||
| [People Data Labs](https://www.peopledatalabs.com) | `@agentic/people-data-labs` | [docs](https://agentic.so/tools/people-data-labs) | People & company data (WIP). |
|
||||
| [Perigon](https://www.goperigon.com/products/news-api) | `@agentic/perigon` | [docs](https://agentic.so/tools/perigon) | Real-time news API and web content data from 140,000+ sources. Structured and enriched by AI, primed for LLMs. |
|
||||
|
|
Ładowanie…
Reference in New Issue