Skip to content

fix: lazy-load optional ai peer#372

Merged
shashi-stackone merged 5 commits into
StackOneHQ:mainfrom
bozicovichsantiago20-oss:fix-optional-ai-peer-import
Jul 7, 2026
Merged

fix: lazy-load optional ai peer#372
shashi-stackone merged 5 commits into
StackOneHQ:mainfrom
bozicovichsantiago20-oss:fix-optional-ai-peer-import

Conversation

@bozicovichsantiago20-oss

@bozicovichsantiago20-oss bozicovichsantiago20-oss commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • remove the top-level runtime import from the optional ai peer
  • load ai through tryImport() only when toClaudeAgentSdkTool() needs jsonSchema
  • keep the existing install hint behavior aligned with toAISDK()

Fixes #327.

Validation

  • pnpm run build
  • clean consumer with packed tarball, @stackone/ai + zod installed and **no ai peer installed: import('@stackone/ai')now printsimport ok function`

I also ran pnpm exec vitest run src/tool.test.ts; the 47 runtime tests passed, but the command exits non-zero because the configured Vitest typecheck worker cannot spawn tsc in this checkout (typescript is not installed as a dev dependency).


Summary by cubic

Lazy-load the optional ai peer so it’s only imported when jsonSchema is needed, preventing runtime errors when ai isn’t installed; fixes #327. Adds tests to guard against regressions.

  • Bug Fixes
    • Removed the top-level runtime import from ai (kept type-only JSONSchema7).
    • Load ai on demand in toClaudeAgentSdkTool() via tryImport() with an install hint using peerDependencies.ai.
    • Added tests to verify the install hint error and ensure the built ESM has no top-level ai import and the built CJS has no top-level require('ai').

Written for commit 17315ea. Summary will update on new commits.

Review in cubic

Copilot AI review requested due to automatic review settings June 7, 2026 16:28
@bozicovichsantiago20-oss bozicovichsantiago20-oss requested a review from a team as a code owner June 7, 2026 16:28

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Updates tool schema generation to avoid a hard runtime dependency on ai by switching from a static import to a dynamic import at the point of use.

Changes:

  • Replaced runtime ai import (jsonSchema) with a type-only import for JSONSchema7.
  • Added dynamic tryImport('ai') usage and switched schema creation to ai.jsonSchema(...).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/tool.ts
Comment thread src/tool.ts
Comment thread src/tool.ts
cubic-dev-ai[bot]
cubic-dev-ai Bot previously approved these changes Jun 7, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

Auto-approved: This change safely lazy-loads the optional ai peer dependency inside toClaudeAgentSdkTool() to prevent runtime errors when ai is not installed, with no observable impact on functionality for users who have it installed.

Re-trigger cubic

@shashi-stackone

Copy link
Copy Markdown
Contributor

Hi @bozicovichsantiago20-oss

Thanks for this. The diagnosis seems correct. The built dist/src/tool.mjs does carry a top-level import { jsonSchema } from "ai", which crashes module load when the optional ai peer isn't installed, and routing it through tryImport (matching toAISDK()) looks like the right fix.

Before we take next action, we'd like this brought up to the bar we hold all fixes to. The main item is a regression test, since right now nothing prevents the eager import from silently coming back:

  1. Friendly-error test for toClaudeAgentSdkTool(). Please add a unit test asserting that when the ai import fails, the method rejects with StackOneError and the install-hint message, which is the same contract toAISDK() relies on. ai is always installed in this repo, so simulate absence by mocking the import boundary. The existing pattern to follow is in src/utils/try-import.test.ts. At the tool.ts level you can vi.mock('./utils/try-import', ...) to make tryImport reject for 'ai', then assert on the thrown StackOneError.

  2. Guard the actual ai peer dependency is not truly optional — top-level static import in tool.mjs crashes on load #327 symptom. The user-facing guarantee is that import('@stackone/ai') succeeds with no ai installed. A lightweight way to lock that in is a test that reads the built dist/src/tool.mjs and asserts it contains no top-level from "ai" import. If you'd rather not assert on build output, the repro from ai peer dependency is not truly optional — top-level static import in tool.mjs crashes on load #327 (packed tarball, ai absent) documented as a validation step is a fine substitute.

  3. Green suite. Please make sure the test run actually completes. The typecheck worker not finding tsc in your checkout means validation didn't fully run. pnpm install should provide the dev toolchain, and once tests pass locally, CI here will confirm.

Could you also confirm the fix against the exact reproduction in #327 (packed tarball, ai not installed, import('@stackone/ai'))? That is the scenario that matters to the reporter.

Appreciated.

@bozicovichsantiago20-oss

Copy link
Copy Markdown
Contributor Author

Thanks — I pushed a follow-up commit addressing the regression coverage requests.

What changed:

  • Added a unit test that mocks the ai import boundary and asserts toClaudeAgentSdkTool() rejects with StackOneError plus the install-hint message.
  • Added a regression test that reads the built dist/src/tool.mjs and asserts there is no top-level from ai import.

Validation I ran locally:

One caveat from this Windows checkout: the full pnpm test run still trips Vitest's typecheck worker because tsc is not available in this local environment outside the repo's normal toolchain/Nix shell, so the focused tests and packed-tarball repro were the most reliable local validations I could run here. CI on the PR should confirm the full suite in the expected environment.

cubic-dev-ai[bot]
cubic-dev-ai Bot previously approved these changes Jun 10, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 1 file (changes from recent commits).

Auto-approved: This change safely defers the optional ai peer import to runtime, preventing crashes when the package is missing, and is well-covered by new tests that validate both the error behavior and the absence of top-level imports.

Re-trigger cubic

@pkg-pr-new

pkg-pr-new Bot commented Jul 7, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/StackOneHQ/stackone-ai-node/@stackone/ai@372

commit: 17315ea

cubic-dev-ai[bot]
cubic-dev-ai Bot previously approved these changes Jul 7, 2026

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 1 file (changes from recent commits).

Auto-approved: Lazy-load optional ai peer to prevent runtime errors; adds tests for the fallback behavior.

Re-trigger cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 1 file (changes from recent commits).

Auto-approved: Lazy-load optional 'ai' peer to fix runtime error when not installed. Isolated change with test coverage and no broader system impact.

Re-trigger cubic

@shashi-stackone

Copy link
Copy Markdown
Contributor

Thanks @bozicovichsantiago20-oss changes looks ok and just needs to fix some CI issues and tests. I have updated the PR and its being reviewed internally. We will merge if all goes well. Thanks for your contribution in fixing this issue.

@shashi-stackone shashi-stackone merged commit e7e944d into StackOneHQ:main Jul 7, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ai peer dependency is not truly optional — top-level static import in tool.mjs crashes on load

3 participants