From 120fe2c6b08b66ef92ceafa0167e1ddc5b0bf266 Mon Sep 17 00:00:00 2001 From: Travis Fischer Date: Thu, 20 Mar 2025 17:37:16 +0800 Subject: [PATCH] feat: add the xsAI SDK --- docs/mint.json | 3 +- docs/sdks/xsai.mdx | 103 +++++++++++++ docs/usage.mdx | 4 + examples/xsai/bin/weather.ts | 30 ++++ examples/xsai/package.json | 20 +++ examples/xsai/tsconfig.json | 5 + packages/core/src/create-ai-function.ts | 1 - packages/xsai/package.json | 47 ++++++ packages/xsai/readme.md | 24 +++ packages/xsai/src/index.ts | 1 + packages/xsai/src/xsai.test.ts | 12 ++ packages/xsai/src/xsai.ts | 23 +++ packages/xsai/tsconfig.json | 5 + pnpm-lock.yaml | 185 ++++++++++++++++++++++++ pnpm-workspace.yaml | 4 + readme.md | 5 + 16 files changed, 470 insertions(+), 2 deletions(-) create mode 100644 docs/sdks/xsai.mdx create mode 100644 examples/xsai/bin/weather.ts create mode 100644 examples/xsai/package.json create mode 100644 examples/xsai/tsconfig.json create mode 100644 packages/xsai/package.json create mode 100644 packages/xsai/readme.md create mode 100644 packages/xsai/src/index.ts create mode 100644 packages/xsai/src/xsai.test.ts create mode 100644 packages/xsai/src/xsai.ts create mode 100644 packages/xsai/tsconfig.json diff --git a/docs/mint.json b/docs/mint.json index 9d769a2..4ba5c79 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -48,7 +48,8 @@ "sdks/genkit", "sdks/dexter", "sdks/openai", - "sdks/genaiscript" + "sdks/genaiscript", + "sdks/xsai" ] }, { diff --git a/docs/sdks/xsai.mdx b/docs/sdks/xsai.mdx new file mode 100644 index 0000000..0cbd041 --- /dev/null +++ b/docs/sdks/xsai.mdx @@ -0,0 +1,103 @@ +--- +title: xsAI SDK +description: Agentic adapter for the xsAI SDK. +--- + +- package: `@agentic/xsai` +- exports: `function createXSAISDKTools` +- [source](https://github.com/transitive-bullshit/agentic/blob/main/packages/xsai/src/xsai.ts) +- [xsAI SDK docs](https://xsai.js.org) + +## Install + + +```bash npm +npm install @agentic/xsai xsai @xsai/tool +``` + +```bash yarn +yarn add @agentic/xsai xsai @xsai/tool +``` + +```bash pnpm +pnpm add @agentic/xsai xsai @xsai/tool +``` + + + +## Usage + + + Note that `createXSAISDKTools` is `async` because `xsai`'s underlying + `xsschema.toJsonSchema` is async. + + +```ts +import 'dotenv/config' + +import { WeatherClient } from '@agentic/weather' +import { createXSAISDKTools } from '@agentic/xsai' +import { generateText } from 'xsai' + +async function main() { + const weather = new WeatherClient() + + const result = await generateText({ + apiKey: process.env.OPENAI_API_KEY!, + baseURL: 'https://api.openai.com/v1/', + model: 'gpt-4o-mini', + tools: await createXSAISDKTools(weather), + toolChoice: 'required', + temperature: 0, + messages: [ + { + role: 'system', + content: 'You are a helpful assistant. Be as concise as possible.' + }, + { role: 'user', content: 'What is the weather in San Francisco?' } + ] + }) + + console.log(JSON.stringify(result, null, 2)) +} + +await main() +``` + +Note that this example snippet also requires you to install the Agentic weather tool and `dotenv`. + + +```bash npm +npm install @agentic/weather dotenv +``` + +```bash yarn +yarn add @agentic/weather dotenv +``` + +```bash pnpm +pnpm add @agentic/weather dotenv +``` + + + +## Running this example + + + You'll need a free API key from [weatherapi.com](https://www.weatherapi.com) + to run this example. Store it in a local `.env` file as `WEATHER_API_KEY`. + + + + You'll need an [OpenAI API key](https://platform.openai.com/docs/quickstart) + to run this example. Store it in a local `.env` file as `OPENAI_API_KEY`. + + +```sh +git clone git@github.com:transitive-bullshit/agentic.git +cd agentic +pnpm install +echo 'WEATHER_API_KEY=your-key' >> .env +echo 'OPENAI_API_KEY=your-key' >> .env +npx tsx examples/xsai/bin/weather.ts +``` diff --git a/docs/usage.mdx b/docs/usage.mdx index b2e0891..ea4addd 100644 --- a/docs/usage.mdx +++ b/docs/usage.mdx @@ -123,4 +123,8 @@ You can pass as many of these `AIFunctionLike` objects as you'd like and you can Using Agentic with OpenAI directly. + + + Using Agentic with the xsAI SDK. + diff --git a/examples/xsai/bin/weather.ts b/examples/xsai/bin/weather.ts new file mode 100644 index 0000000..3028a1c --- /dev/null +++ b/examples/xsai/bin/weather.ts @@ -0,0 +1,30 @@ +/* eslint-disable no-process-env */ +import 'dotenv/config' + +import { WeatherClient } from '@agentic/weather' +import { createXSAISDKTools } from '@agentic/xsai' +import { generateText } from 'xsai' + +async function main() { + const weather = new WeatherClient() + + const result = await generateText({ + apiKey: process.env.OPENAI_API_KEY!, + baseURL: 'https://api.openai.com/v1/', + model: 'gpt-4o-mini', + tools: await createXSAISDKTools(weather), + toolChoice: 'required', + temperature: 0, + messages: [ + { + role: 'system', + content: 'You are a helpful assistant. Be as concise as possible.' + }, + { role: 'user', content: 'What is the weather in San Francisco?' } + ] + }) + + console.log(JSON.stringify(result, null, 2)) +} + +await main() diff --git a/examples/xsai/package.json b/examples/xsai/package.json new file mode 100644 index 0000000..db42390 --- /dev/null +++ b/examples/xsai/package.json @@ -0,0 +1,20 @@ +{ + "name": "agentic-examples-xsai", + "type": "module", + "private": true, + "scripts": { + "test": "run-s test:*", + "test:lint": "eslint .", + "test:typecheck": "tsc --noEmit" + }, + "dependencies": { + "@agentic/xsai": "workspace:*", + "@agentic/weather": "workspace:*", + "xsai": "catalog:", + "@xsai/tool": "catalog:", + "zod": "catalog:" + }, + "devDependencies": { + "@agentic/tsconfig": "workspace:*" + } +} diff --git a/examples/xsai/tsconfig.json b/examples/xsai/tsconfig.json new file mode 100644 index 0000000..b99a3fc --- /dev/null +++ b/examples/xsai/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "@agentic/tsconfig/base.json", + "include": ["bin"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/core/src/create-ai-function.ts b/packages/core/src/create-ai-function.ts index 0e5f8aa..3d1b4e5 100644 --- a/packages/core/src/create-ai-function.ts +++ b/packages/core/src/create-ai-function.ts @@ -85,7 +85,6 @@ export function createAIFunction, Output>( aiFunction.impl = ( params: z.infer ): types.MaybePromise => { - console.error(spec.name, params) return implementation(params) } diff --git a/packages/xsai/package.json b/packages/xsai/package.json new file mode 100644 index 0000000..fa5701d --- /dev/null +++ b/packages/xsai/package.json @@ -0,0 +1,47 @@ +{ + "name": "@agentic/xsai", + "version": "7.5.1", + "description": "Agentic adapter for the xsAI SDK.", + "author": "Travis Fischer ", + "license": "MIT", + "repository": { + "type": "git", + "url": "git+https://github.com/transitive-bullshit/agentic.git" + }, + "type": "module", + "source": "./src/index.ts", + "types": "./dist/index.d.ts", + "sideEffects": false, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js", + "default": "./dist/index.js" + } + }, + "files": [ + "dist" + ], + "scripts": { + "build": "tsup", + "dev": "tsup --watch", + "clean": "del dist", + "test": "run-s test:*", + "test:lint": "eslint .", + "test:typecheck": "tsc --noEmit", + "test:unit": "vitest run" + }, + "dependencies": { + "@agentic/core": "workspace:*" + }, + "peerDependencies": { + "@xsai/tool": "catalog:" + }, + "devDependencies": { + "@agentic/tsconfig": "workspace:*", + "@xsai/tool": "catalog:" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/xsai/readme.md b/packages/xsai/readme.md new file mode 100644 index 0000000..fe5f799 --- /dev/null +++ b/packages/xsai/readme.md @@ -0,0 +1,24 @@ +

+ + Agentic + +

+ +

+ Agentic adapter for the [xsAI SDK](https://github.com/moeru-ai/xsai). +

+ +

+ Build Status + NPM + MIT License + Prettier Code Formatting +

+ +# Agentic + +**See the [github repo](https://github.com/transitive-bullshit/agentic) or [docs](https://agentic.so) for more info.** + +## License + +MIT © [Travis Fischer](https://x.com/transitive_bs) diff --git a/packages/xsai/src/index.ts b/packages/xsai/src/index.ts new file mode 100644 index 0000000..2509fe5 --- /dev/null +++ b/packages/xsai/src/index.ts @@ -0,0 +1 @@ +export * from './xsai' diff --git a/packages/xsai/src/xsai.test.ts b/packages/xsai/src/xsai.test.ts new file mode 100644 index 0000000..96b0af4 --- /dev/null +++ b/packages/xsai/src/xsai.test.ts @@ -0,0 +1,12 @@ +import { EchoAITool } from '@agentic/core' +import { describe, expect, test } from 'vitest' + +import { createXSAISDKTools } from './xsai' + +describe('xsai', () => { + test('createXSAISDKTools', async () => { + const tools = await createXSAISDKTools(new EchoAITool()) + expect(tools).toHaveLength(1) + expect(tools[0]!.function.name).toBe('echo') + }) +}) diff --git a/packages/xsai/src/xsai.ts b/packages/xsai/src/xsai.ts new file mode 100644 index 0000000..d791475 --- /dev/null +++ b/packages/xsai/src/xsai.ts @@ -0,0 +1,23 @@ +import { type AIFunctionLike, AIFunctionSet } from '@agentic/core' +import { tool, type ToolResult } from '@xsai/tool' + +/** + * Converts a set of Agentic stdlib AI functions to an object compatible with + * [the xsAI SDK's](https://github.com/moeru-ai/xsai) `tools` parameter. + */ +export function createXSAISDKTools( + ...aiFunctionLikeTools: AIFunctionLike[] +): Promise { + const fns = new AIFunctionSet(aiFunctionLikeTools) + + return Promise.all( + fns.map((fn) => + tool({ + name: fn.spec.name, + description: fn.spec.description, + parameters: fn.inputSchema, + execute: fn.impl + }) + ) + ) +} diff --git a/packages/xsai/tsconfig.json b/packages/xsai/tsconfig.json new file mode 100644 index 0000000..6c8d720 --- /dev/null +++ b/packages/xsai/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "@agentic/tsconfig/base.json", + "include": ["src"], + "exclude": ["node_modules", "dist"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e4dafdb..a6992d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -30,6 +30,9 @@ catalogs: '@types/jsrsasign': specifier: ^10.5.15 version: 10.5.15 + '@xsai/tool': + specifier: ^0.1.3 + version: 0.1.3 ai: specifier: ^4.1.61 version: 4.1.61 @@ -90,6 +93,9 @@ catalogs: wikibase-sdk: specifier: ^10.2.2 version: 10.2.2 + xsai: + specifier: ^0.1.3 + version: 0.1.3 zod: specifier: ^3.24.2 version: 3.24.2 @@ -350,6 +356,28 @@ importers: specifier: workspace:* version: link:../../packages/tsconfig + examples/xsai: + dependencies: + '@agentic/weather': + specifier: workspace:* + version: link:../../packages/weather + '@agentic/xsai': + specifier: workspace:* + version: link:../../packages/xsai + '@xsai/tool': + specifier: 'catalog:' + version: 0.1.3(zod-to-json-schema@3.24.3(zod@3.24.2)) + xsai: + specifier: 'catalog:' + version: 0.1.3(zod-to-json-schema@3.24.3(zod@3.24.2)) + zod: + specifier: 'catalog:' + version: 3.24.2 + devDependencies: + '@agentic/tsconfig': + specifier: workspace:* + version: link:../../packages/tsconfig + packages/ai-sdk: dependencies: '@agentic/core': @@ -1245,6 +1273,19 @@ importers: specifier: workspace:* version: link:../tsconfig + packages/xsai: + dependencies: + '@agentic/core': + specifier: workspace:* + version: link:../core + devDependencies: + '@agentic/tsconfig': + specifier: workspace:* + version: link:../tsconfig + '@xsai/tool': + specifier: 'catalog:' + version: 0.1.3(zod-to-json-schema@3.24.3(zod@3.24.2)) + packages/zoominfo: dependencies: '@agentic/core': @@ -3318,6 +3359,45 @@ packages: '@vitest/utils@3.0.9': resolution: {integrity: sha512-ilHM5fHhZ89MCp5aAaM9uhfl1c2JdxVxl3McqsdVyVNN6JffnEen8UMCdRTzOhGXNQGo5GNL9QugHrz727Wnng==} + '@xsai/embed@0.1.3': + resolution: {integrity: sha512-knhTsu1jiiVvXZeqeJFIBjMQDIBfS9gVe7ZuBU4jVnd+JbHle8/RUlOfzlZdHTcW0gFb5ekrJePa/HiTyAFRzQ==} + + '@xsai/generate-object@0.1.3': + resolution: {integrity: sha512-dChrTi0vMxFzTG16GXhjuKjTGj5AbvfI2q/ml7CWEnjDmQV5yjM/8hIAE/5UokvcJt3YZI6RyVkt+P6xlbExkA==} + + '@xsai/generate-speech@0.1.3': + resolution: {integrity: sha512-ZiJZZh1TF7dX3UH4vJYna5kML5eLOiEuLolUzJJuWvSeJgGwHs6/kD7n6k4zYwSrbxGCvkPkkijrVSf65R5okQ==} + + '@xsai/generate-text@0.1.3': + resolution: {integrity: sha512-jdA7w0yPU7ri0tqj1AXgZ2nYj42sN2V7fwhjo9RpbEagZm0jrRBNgRoVaViyQzbZh3CRCPdUVUmLMojq8VOTLw==} + + '@xsai/generate-transcription@0.1.3': + resolution: {integrity: sha512-E4zJZkLDO8svGYewNZblgDCb2biPj/c06H6Z6H7d1hZXeqlECnkYTr7+T414ndp5ngYo2yRxxCRykjxcVN3O+A==} + + '@xsai/model@0.1.3': + resolution: {integrity: sha512-C6feX4fl8JjHhjqoXtSnzbAxIf1ML/SLHuPh2q0zvTujBDvM4s1zyRBtH3tngSuVkxtxxGchkuS76eXDjdW6UQ==} + + '@xsai/shared-chat@0.1.3': + resolution: {integrity: sha512-vRI7KUf3CUQNXJcNB/fOWIAEAuv48/VeOLQCmiRDbM8EQaWoR6alF4UDz4G5EAYOF4zbu2EngcsUxKqonSxylw==} + + '@xsai/shared@0.1.3': + resolution: {integrity: sha512-PR4QJque+qQufl6YUE0NaH/hhhXIeIomzEuTtOJ1u8pDpdY7aiBJJtYWkwLT6x05nvwRAmDAsBa+c6jyJX8bdQ==} + + '@xsai/stream-object@0.1.3': + resolution: {integrity: sha512-P24g1ts7nu+8XiaqWmO0n4fRWwANEuPxyg71e9qvyjQ/ZfjKmHEOWtP8KoU5oLIo2b9808lg1HDS9Eoeea/bkg==} + + '@xsai/stream-text@0.1.3': + resolution: {integrity: sha512-NVV1hwS1TTf8T++M9ew0FTH1U08EFk5LymW2HEVMMVmdUHeKvYqkvOXwFicGYhZsMVRXZqA8b8A8usEHFMsBIg==} + + '@xsai/tool@0.1.3': + resolution: {integrity: sha512-Qf+FRpvCAEF4Is7XkFr52P/cI0JDunbYPV+3dAdG0c/QtB7g+hwVgKQLcwIMtg2IZNGy7ggSGVBZZtNPBUnjyQ==} + + '@xsai/utils-chat@0.1.3': + resolution: {integrity: sha512-wXx7CL5sEkvEI4dUDYwuA1mwAnQ5y5ugnLoRGcXtiXf8l3isz7+HOKER5gupzCoy9CsLkPSWnW21GNuXqFObxQ==} + + '@xsai/utils-stream@0.1.3': + resolution: {integrity: sha512-bP4QQL+DbDQ9Y4S+IJAFLjI0J7Yn2kpaKt4+w1SfQxAGYHxX8Na9Anmn8nHQJv5gBmUaR/wN2IwgXcPE1u+MvA==} + abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} @@ -6476,6 +6556,23 @@ packages: utf-8-validate: optional: true + xsai@0.1.3: + resolution: {integrity: sha512-JVQI2Mdr/NU8ed4D40u1rQqBDwCigjtuM2RQn0hd91iCBB54zCsKoQkFq7uVc0hSEMPn755SwRHgM0LXWrVy9Q==} + + xsschema@0.1.3: + resolution: {integrity: sha512-hU0s8RLGPMDKWvQ1ShkNSXrEZGgndA/6aMQLhoFBXLcbG2yvUTX+Q4WJ8CCIefK2aEkMDRjD9BuqhaQodd0g/g==} + peerDependencies: + '@valibot/to-json-schema': ^1.0.0-rc.0 + arktype: ^2.0.4 + zod-to-json-schema: ^3.24.1 + peerDependenciesMeta: + '@valibot/to-json-schema': + optional: true + arktype: + optional: true + zod-to-json-schema: + optional: true + xstate@5.19.2: resolution: {integrity: sha512-B8fL2aP0ogn5aviAXFzI5oZseAMqN00fg/TeDa3ZtatyDcViYLIfuQl4y8qmHCiKZgGEzmnTyNtNQL9oeJE2gw==} @@ -9237,6 +9334,70 @@ snapshots: loupe: 3.1.3 tinyrainbow: 2.0.0 + '@xsai/embed@0.1.3': + dependencies: + '@xsai/shared': 0.1.3 + + '@xsai/generate-object@0.1.3(zod-to-json-schema@3.24.3(zod@3.24.2))': + dependencies: + '@xsai/generate-text': 0.1.3 + xsschema: 0.1.3(zod-to-json-schema@3.24.3(zod@3.24.2)) + transitivePeerDependencies: + - '@valibot/to-json-schema' + - arktype + - zod-to-json-schema + + '@xsai/generate-speech@0.1.3': + dependencies: + '@xsai/shared': 0.1.3 + + '@xsai/generate-text@0.1.3': + dependencies: + '@xsai/shared-chat': 0.1.3 + + '@xsai/generate-transcription@0.1.3': + dependencies: + '@xsai/shared': 0.1.3 + + '@xsai/model@0.1.3': + dependencies: + '@xsai/shared': 0.1.3 + + '@xsai/shared-chat@0.1.3': + dependencies: + '@xsai/shared': 0.1.3 + + '@xsai/shared@0.1.3': {} + + '@xsai/stream-object@0.1.3(zod-to-json-schema@3.24.3(zod@3.24.2))': + dependencies: + '@xsai/stream-text': 0.1.3 + xsschema: 0.1.3(zod-to-json-schema@3.24.3(zod@3.24.2)) + transitivePeerDependencies: + - '@valibot/to-json-schema' + - arktype + - zod-to-json-schema + + '@xsai/stream-text@0.1.3': + dependencies: + '@xsai/shared-chat': 0.1.3 + + '@xsai/tool@0.1.3(zod-to-json-schema@3.24.3(zod@3.24.2))': + dependencies: + '@xsai/shared': 0.1.3 + '@xsai/shared-chat': 0.1.3 + xsschema: 0.1.3(zod-to-json-schema@3.24.3(zod@3.24.2)) + transitivePeerDependencies: + - '@valibot/to-json-schema' + - arktype + - zod-to-json-schema + + '@xsai/utils-chat@0.1.3': + dependencies: + '@xsai/shared-chat': 0.1.3 + + '@xsai/utils-stream@0.1.3': {} + abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -12649,6 +12810,30 @@ snapshots: ws@8.18.0: {} + xsai@0.1.3(zod-to-json-schema@3.24.3(zod@3.24.2)): + dependencies: + '@xsai/embed': 0.1.3 + '@xsai/generate-object': 0.1.3(zod-to-json-schema@3.24.3(zod@3.24.2)) + '@xsai/generate-speech': 0.1.3 + '@xsai/generate-text': 0.1.3 + '@xsai/generate-transcription': 0.1.3 + '@xsai/model': 0.1.3 + '@xsai/shared': 0.1.3 + '@xsai/shared-chat': 0.1.3 + '@xsai/stream-object': 0.1.3(zod-to-json-schema@3.24.3(zod@3.24.2)) + '@xsai/stream-text': 0.1.3 + '@xsai/tool': 0.1.3(zod-to-json-schema@3.24.3(zod@3.24.2)) + '@xsai/utils-chat': 0.1.3 + '@xsai/utils-stream': 0.1.3 + transitivePeerDependencies: + - '@valibot/to-json-schema' + - arktype + - zod-to-json-schema + + xsschema@0.1.3(zod-to-json-schema@3.24.3(zod@3.24.2)): + optionalDependencies: + zod-to-json-schema: 3.24.3(zod@3.24.2) + xstate@5.19.2: {} xtend@4.0.2: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 775cfb5..14da1f9 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -28,6 +28,10 @@ catalog: ai: ^4.1.61 '@ai-sdk/openai': ^1.2.5 + # xsai + xsai: ^0.1.3 + '@xsai/tool': ^0.1.3 + # genkit genkit: ^1.2.0 genkitx-openai: ^0.20.1 diff --git a/readme.md b/readme.md index 8a63995..34bfe7c 100644 --- a/readme.md +++ b/readme.md @@ -29,6 +29,7 @@ - [Dexa Dexter](#dexa-dexter) - [OpenAI](#openai) - [GenAIScript](#genaiscript) + - [xsAI SDK](#xsai-sdk) - [Tools](#tools) - [Contributors](#contributors) - [License](#license) @@ -123,6 +124,10 @@ Full docs are available at [agentic.so](https://agentic.so). [Agentic support in GenAIScript](https://agentic.so/sdks/genaiscript) +### xsAI SDK + +[Agentic adapter docs for the xsAI SDK](https://agentic.so/sdks/xsai) + ## Tools | Service / Tool | Package | Docs | Description |