diff --git a/.changeset/decouple-neutral-core.md b/.changeset/decouple-neutral-core.md new file mode 100644 index 0000000..e65c7b7 --- /dev/null +++ b/.changeset/decouple-neutral-core.md @@ -0,0 +1,5 @@ +--- +"@gemstack/ai-sdk": minor +--- + +Decouple the core from Rudder: `@gemstack/ai-sdk`'s only required runtime dependency is now `zod`. Schema conversion uses Zod 4's native `z.toJSONSchema` directly instead of `@rudderjs/json-schema` (dependency removed). `@rudderjs/console` is demoted from a hard dependency to an optional peer (only the `/doctor` check and `/commands/make-agent` scaffolder use it). `@rudderjs/core` (`/server` provider) and `@rudderjs/orm` (the `*-orm` stores) remain optional peers behind their opt-in subpaths. A non-Rudder app can now install and use the SDK with zero `@rudderjs/*` packages. No public API change on the main entry. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c585da2..a32f3e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,5 @@ jobs: cache: pnpm - run: pnpm install --frozen-lockfile - run: pnpm build - # TODO(#3): re-enable typecheck + test once @gemstack/ai-sdk is decoupled - # from @rudderjs/core/orm. Today the .test.ts files import broader - # @rudderjs/* packages that aren't dependencies here, so neither passes - # standalone. build (which excludes tests) is the meaningful gate for now. + - run: pnpm typecheck + - run: pnpm test diff --git a/packages/ai-sdk/README.md b/packages/ai-sdk/README.md index 7c22b02..19fef91 100644 --- a/packages/ai-sdk/README.md +++ b/packages/ai-sdk/README.md @@ -25,7 +25,13 @@ pnpm add @aws-sdk/client-bedrock-runtime # AWS Bedrock ## Status -`@gemstack/ai-sdk` starts at `0.1.0`. The code is mature, but the version line is intentionally reset: the public surface is being decoupled from Rudder (the `@rudderjs/core` / `@rudderjs/orm` coupling and the ORM-backed subpaths are moving behind a neutral, optional adapter seam) so the package stands alone in any Node app. Expect the API to firm up toward `1.0.0` as that decoupling lands. +As of `0.2.0` the core stands alone: `@gemstack/ai-sdk`'s only required runtime dependency is `zod`. Every framework integration is an optional, opt-in subpath behind an optional peer dependency: + +- the Rudder `/server` provider (optional peer `@rudderjs/core`) +- the ORM-backed stores `/conversation-orm`, `/memory-orm`, `/budget-orm` (optional peer `@rudderjs/orm`) +- the doctor check + `make:agent` scaffolder (optional peer `@rudderjs/console`) + +The neutral storage contracts (`UserMemory`, `ConversationStore`, `BudgetStorage`) ship in-memory defaults, so a non-Rudder app uses the SDK with zero `@rudderjs/*` installed. The version line stays `0.x` while the API settles toward `1.0.0`. ## Subpath exports diff --git a/packages/ai-sdk/package.json b/packages/ai-sdk/package.json index 322a7ba..9e213be 100644 --- a/packages/ai-sdk/package.json +++ b/packages/ai-sdk/package.json @@ -122,17 +122,19 @@ "clean": "rm -rf dist" }, "dependencies": { - "@rudderjs/console": "^1.4.3", - "@rudderjs/json-schema": "^1.1.0", "zod": "^4.0.0" }, "peerDependencies": { "@modelcontextprotocol/sdk": "^1.29.0", + "@rudderjs/console": "^1.4.3", "@rudderjs/core": "^1.13.3", "@rudderjs/orm": "^1.22.0", "react": ">=19.2.0" }, "peerDependenciesMeta": { + "@rudderjs/console": { + "optional": true + }, "@rudderjs/core": { "optional": true }, diff --git a/packages/ai-sdk/src/zod-to-json-schema.ts b/packages/ai-sdk/src/zod-to-json-schema.ts index 1b1bb01..a61ae3d 100644 --- a/packages/ai-sdk/src/zod-to-json-schema.ts +++ b/packages/ai-sdk/src/zod-to-json-schema.ts @@ -1,18 +1,26 @@ -import type { z } from 'zod' -import { convertSchema, type SchemaIo } from '@rudderjs/json-schema' +import { z } from 'zod' + +/** Request (tool parameters) vs response (structured output) projection. */ +export type SchemaIo = 'input' | 'output' /** * Zod → JSON Schema for tool/output definitions. * - * Delegates to the framework's shared, validator-agnostic converter - * (`@rudderjs/json-schema`), which dispatches on the Standard Schema vendor tag - * and uses Zod 4's native `z.toJSONSchema` — the same converter `@rudderjs/openapi` - * uses. Falls back to an open object schema when the converter can't represent - * the schema, so tool/output definitions always have *some* parameter shape. + * Uses Zod 4's native `z.toJSONSchema` directly (Zod is a hard dependency), so + * the package carries no framework coupling for schema conversion. Strips the + * `$schema` dialect key (provider tool/output schemas don't want it) and falls + * back to an open object schema when a schema can't be represented, so + * tool/output definitions always have *some* parameter shape. * - * `io` selects the request (`'input'` — tool parameters) vs response - * (`'output'` — structured output) projection; defaults to `'output'`. + * `io` selects the request (`'input'`, tool parameters) vs response + * (`'output'`, structured output) projection; defaults to `'output'`. */ export function zodToJsonSchema(schema: z.ZodType, io: SchemaIo = 'output'): Record { - return convertSchema(schema, io) ?? { type: 'object' } + try { + const out = z.toJSONSchema(schema, { io }) as Record + delete out.$schema + return out + } catch { + return { type: 'object' } + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b842600..d566e19 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,12 +20,6 @@ importers: packages/ai-sdk: dependencies: - '@rudderjs/console': - specifier: ^1.4.3 - version: 1.4.3 - '@rudderjs/json-schema': - specifier: ^1.1.0 - version: 1.1.0 zod: specifier: ^4.0.0 version: 4.4.3 @@ -33,6 +27,9 @@ importers: '@modelcontextprotocol/sdk': specifier: ^1.29.0 version: 1.29.0(zod@4.4.3) + '@rudderjs/console': + specifier: ^1.4.3 + version: 1.4.3 '@rudderjs/core': specifier: ^1.13.3 version: 1.13.3 @@ -353,10 +350,6 @@ packages: postgres: optional: true - '@rudderjs/json-schema@1.1.0': - resolution: {integrity: sha512-HMfuxXdJVE75W6Rk4VxXdoyfJWrXr4xixjt9SJQhjkSRmPYyhoxeIJKp0AlpAvpG584+H24gFOs+VDdvP5JhYQ==} - engines: {node: '>=22.12.0'} - '@rudderjs/orm@1.22.0': resolution: {integrity: sha512-c8E99UkKv7TaT3J748I8VwY+6Roztw/OfSKhbIQoqzk41kjaV6VdzoPpcpr6okrdkMNuO8zb+AGzIUAoZwASRQ==} engines: {node: '>=22.12.0'} @@ -1874,11 +1867,6 @@ snapshots: dependencies: '@rudderjs/contracts': 1.19.0 - '@rudderjs/json-schema@1.1.0': - dependencies: - '@rudderjs/contracts': 1.19.0 - zod: 4.4.3 - '@rudderjs/orm@1.22.0(@rudderjs/console@1.4.3)(@rudderjs/core@1.13.3)': dependencies: '@rudderjs/contracts': 1.19.0