-
Notifications
You must be signed in to change notification settings - Fork 3
feat(examples): add TanStack AI and Claude Agent SDK integrations with E2E tests #222
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This reverts commit e7372a4.
- Define comprehensive JSONSchema interface in types.ts covering all JSON Schema draft-07 properties - Add toJsonSchema() method to BaseTool and Tools classes for framework-agnostic schema export - Refactor toOpenAI(), toAnthropic(), and toOpenAIResponses() to use toJsonSchema() internally, reducing code duplication - Use type-fest OverrideProperties for ObjectJSONSchema type to ensure type: 'object' is always set - Remove json-schema and @types/json-schema dependencies This reduces external dependencies while providing a more flexible JSONSchema type that works seamlessly with OpenAI, Anthropic, and other LLM providers.
Consolidate schema generation by reusing toJsonSchema() instead of manually constructing the schema object. This reduces duplication and ensures consistency across all conversion methods.
- Import JSONSchema7 type from @ai-sdk/provider as AISDKJSONSchema - Use satisfies AISDKJSONSchema to validate schema at compile time - Move jsonSchema type import to top-level for cleaner code - Add @ai-sdk/provider as dev dependency for type checking
- Create tryImport() helper function for dynamic imports with friendly error messages when optional dependencies are not installed - Refactor toAISDK() to use tryImport() for cleaner code - Remove unused jsonSchema type import from top-level
- Test successful import of existing modules - Test StackOneError is thrown for non-existent modules - Verify error message includes module name and install hint
- Remove deprecated v4 parameters property - Use satisfies for type-safe tool definition - Remove outdated TODO comment about ts-ignore - Simplify tool definition by constructing all properties upfront
Add comprehensive E2E tests for all example files using MSW mocks: - fetch-tools.test.ts: tests tool fetching, filtering, and execution - ai-sdk-integration.test.ts: tests AI SDK with OpenAI provider - openai-integration.test.ts: tests OpenAI Chat Completions API - openai-responses-integration.test.ts: tests OpenAI Responses API These tests verify the examples work correctly with mocked API responses, ensuring documentation examples remain functional.
- Add exampleBamboohrTools with list, get, and create employee tools - Register example account IDs in MCP handlers - Add OpenAI Responses API handler for employee lookup pattern - Fix extractTextFromInput to handle plain string input These mock handlers support the new E2E tests for example files.
…x.ts - Move runtime dependencies (openai, ai, @ai-sdk/openai) to dependencies - Add msw to devDependencies for testing - Remove unused zod dependency - Add vitest/globals types for test file support - Delete redundant index.ts (duplicates fetch-tools.ts functionality) The dependency reorganisation reflects actual usage: runtime deps are used by example scripts, while msw is only needed for testing.
- Move setupFiles to root level (inherited via extends: true) - Limit coverage to src/**/*.ts only (examples are documentation) - Remove redundant per-project setupFiles configuration The setupFiles change reduces duplication since both root and examples projects use the same MSW setup. Coverage excludes examples since they are documentation files, not library code.
- Add *.test.ts to examples entry points in knip config - Remove lefthook from ignoreDependencies (no longer needed) - Add examples/*.ts to package.json files for distribution - Exclude example test files from distribution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This pull request adds comprehensive E2E tests for example integrations using MSW mocks, reorganizes example dependencies to distinguish runtime from development dependencies, and consolidates vitest configuration. The changes include removing redundant example files and adding new test infrastructure to validate example code behavior.
- Adds E2E tests for all example integration files (fetch-tools, ai-sdk-integration, openai-integration, openai-responses-integration)
- Reorganizes examples/package.json to move runtime dependencies (AI SDK, OpenAI, etc.) from devDependencies to dependencies
- Consolidates vitest setupFiles to root level configuration (inherited via extends: true)
- Removes redundant index.ts and renames interactive-cli.ts to fetch-tools-debug.ts
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| vitest.config.ts | Moves setupFiles to root level for inheritance; limits coverage to src/ only |
| package.json | Adds examples/*.ts to files array for npm package (with typo in exclusion pattern) |
| pnpm-lock.yaml | Updates dependency locations reflecting examples/package.json reorganization |
| examples/package.json | Moves @ai-sdk/openai, @clack/prompts, ai, openai to runtime dependencies; adds msw to devDependencies |
| examples/tsconfig.json | Adds vitest/globals to types array for global test utilities |
| knip.config.ts | Adds *.test.ts to examples entry points; removes lefthook from ignoreDependencies (incorrectly) |
| mocks/mcp-server.ts | Adds exampleBamboohrTools with list, get, and create employee tools for testing |
| mocks/handlers.mcp.ts | Registers 'your-bamboohr-account-id' and 'your-stackone-account-id' with exampleBamboohrTools |
| mocks/handlers.openai.ts | Adds handler for OpenAI Responses API employee lookup pattern |
| mocks/handlers.utils.ts | Fixes extractTextFromInput to handle plain string input |
| examples/fetch-tools.test.ts | New E2E test validating tool fetching, filtering, and execution |
| examples/ai-sdk-integration.test.ts | New E2E test for AI SDK with OpenAI provider integration |
| examples/openai-integration.test.ts | New E2E test for OpenAI Chat Completions API integration |
| examples/openai-responses-integration.test.ts | New E2E test for OpenAI Responses API integration |
| examples/fetch-tools-debug.ts | Renamed/enhanced interactive CLI (was interactive-cli.ts) with doc comment issue |
| examples/index.ts | Removed redundant example file |
| examples/interactive-cli.ts | Removed (replaced by fetch-tools-debug.ts) |
| examples/sample-document.txt | Removed unused test file |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ignore: ['**/*.test.ts', '**/*.spec.ts', '**/*.test-d.ts'], | ||
| ignoreBinaries: ['only-allow'], | ||
| ignoreDependencies: ['@typescript/native-preview', 'lefthook'], | ||
| ignoreDependencies: ['@typescript/native-preview'], |
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing 'lefthook' from ignoreDependencies will cause knip to report it as unused. However, lefthook is used via the lefthook.yaml configuration file in the root directory, which knip may not detect. The 'lefthook' entry should remain in ignoreDependencies.
| ignoreDependencies: ['@typescript/native-preview'], | |
| ignoreDependencies: ['@typescript/native-preview', 'lefthook'], |
examples/fetch-tools-debug.ts
Outdated
| * | ||
| * Run with: | ||
| * ```bash | ||
| * npx tsx examples/interactive-cli.ts |
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment references 'examples/interactive-cli.ts' but this file is actually 'examples/fetch-tools-debug.ts'. The Run command should be updated to reference the correct filename.
| * npx tsx examples/interactive-cli.ts | |
| * npx tsx examples/fetch-tools-debug.ts |
| "LICENSE" | ||
| "LICENSE", | ||
| "examples/*.ts", | ||
| "!example/*.test.ts" |
Copilot
AI
Dec 12, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in the glob pattern: "example/.test.ts" should be "examples/.test.ts" (missing the 's'). This will fail to properly exclude test files from the package.
| "!example/*.test.ts" | |
| "!examples/*.test.ts" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 issues found across 18 files
Prompt for AI agents (all 3 issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="package.json">
<violation number="1" location="package.json:20">
P1: Typo in exclusion pattern: `!example/*.test.ts` should be `!examples/*.test.ts` (plural). The current pattern won't exclude any test files because the directory is named `examples`, not `example`.</violation>
</file>
<file name="knip.config.ts">
<violation number="1" location="knip.config.ts:16">
P2: Removing `lefthook` from `ignoreDependencies` will cause knip to report it as unused. Lefthook is a git hooks CLI tool (configured via `lefthook.yaml`) that has no code imports, so it needs to stay in the ignore list.</violation>
</file>
<file name="examples/fetch-tools-debug.ts">
<violation number="1" location="examples/fetch-tools-debug.ts:14">
P2: Documentation mismatch: the run command references `interactive-cli.ts` but this file is named `fetch-tools-debug.ts`. Either rename the file or update the documentation to match.</violation>
</file>
Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR
| "LICENSE" | ||
| "LICENSE", | ||
| "examples/*.ts", | ||
| "!example/*.test.ts" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: Typo in exclusion pattern: !example/*.test.ts should be !examples/*.test.ts (plural). The current pattern won't exclude any test files because the directory is named examples, not example.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At package.json, line 20:
<comment>Typo in exclusion pattern: `!example/*.test.ts` should be `!examples/*.test.ts` (plural). The current pattern won't exclude any test files because the directory is named `examples`, not `example`.</comment>
<file context>
@@ -15,7 +15,9 @@
- "LICENSE"
+ "LICENSE",
+ "examples/*.ts",
+ "!example/*.test.ts"
],
"scripts": {
</file context>
| ignore: ['**/*.test.ts', '**/*.spec.ts', '**/*.test-d.ts'], | ||
| ignoreBinaries: ['only-allow'], | ||
| ignoreDependencies: ['@typescript/native-preview', 'lefthook'], | ||
| ignoreDependencies: ['@typescript/native-preview'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Removing lefthook from ignoreDependencies will cause knip to report it as unused. Lefthook is a git hooks CLI tool (configured via lefthook.yaml) that has no code imports, so it needs to stay in the ignore list.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At knip.config.ts, line 16:
<comment>Removing `lefthook` from `ignoreDependencies` will cause knip to report it as unused. Lefthook is a git hooks CLI tool (configured via `lefthook.yaml`) that has no code imports, so it needs to stay in the ignore list.</comment>
<file context>
@@ -7,13 +7,13 @@ export default {
ignore: ['**/*.test.ts', '**/*.spec.ts', '**/*.test-d.ts'],
ignoreBinaries: ['only-allow'],
- ignoreDependencies: ['@typescript/native-preview', 'lefthook'],
+ ignoreDependencies: ['@typescript/native-preview'],
rules: {
optionalPeerDependencies: 'off',
</file context>
| ignoreDependencies: ['@typescript/native-preview'], | |
| ignoreDependencies: ['@typescript/native-preview', 'lefthook'], |
examples/fetch-tools-debug.ts
Outdated
| * | ||
| * Run with: | ||
| * ```bash | ||
| * npx tsx examples/interactive-cli.ts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Documentation mismatch: the run command references interactive-cli.ts but this file is named fetch-tools-debug.ts. Either rename the file or update the documentation to match.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At examples/fetch-tools-debug.ts, line 14:
<comment>Documentation mismatch: the run command references `interactive-cli.ts` but this file is named `fetch-tools-debug.ts`. Either rename the file or update the documentation to match.</comment>
<file context>
@@ -0,0 +1,297 @@
+ *
+ * Run with:
+ * ```bash
+ * npx tsx examples/interactive-cli.ts
+ * ```
+ */
</file context>
- Create new 'examples' catalog for example-specific dependencies - Add @tanstack/ai and @tanstack/ai-openai for TanStack AI integration - Add @anthropic-ai/claude-agent-sdk for Claude Agent SDK integration - Configure minimumReleaseAgeExclude for newly released packages - Update examples/package.json to use catalog:examples references
- Add tanstack-ai-integration.ts demonstrating StackOne tools with TanStack AI - TanStack AI requires Zod schemas for tool input validation - Add E2E tests for tool setup and direct execution - The adapter reads OPENAI_API_KEY from environment automatically
- Add claude-agent-sdk-integration.ts demonstrating StackOne tools with Claude Agent SDK - Create custom MCP server using createSdkMcpServer() with StackOne tools - Wrap StackOne tools using tool() function with Zod schemas - Add E2E tests for tool wrapper, MCP server creation, and direct execution - Note: Actual query execution requires ANTHROPIC_API_KEY and claude-code installation
- Document that stepCountIs() creates an agent-like multi-step tool loop - Reference AI SDK v6+ ToolLoopAgent for explicit agent functionality
- Add TanStack AI integration section with Zod schema example - Add Claude Agent SDK integration section with MCP server example - Remove obsolete link to deleted examples/index.ts
commit: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5 issues found across 31 files
Prompt for AI agents (all 5 issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="src/utils/try-import.ts">
<violation number="1" location="src/utils/try-import.ts:20">
P2: Catch block catches all import errors indiscriminately. If the module is installed but has a syntax error or initialization failure, users will see a misleading "not installed" message. Consider checking for the specific error code (`ERR_MODULE_NOT_FOUND`) and re-throwing other errors to avoid masking real issues.</violation>
</file>
<file name="package.json">
<violation number="1" location="package.json:20">
P1: Typo in exclusion pattern: `!example/*.test.ts` should be `!examples/*.test.ts` (plural). This mismatch means test files will be incorrectly included in the published npm package.</violation>
</file>
<file name="examples/package.json">
<violation number="1" location="examples/package.json:15">
P1: Missing `zod` dependency. The `zod` package was removed but is still imported in `claude-agent-sdk-integration.ts`, `tanstack-ai-integration.ts`, and `claude-agent-sdk-integration.test.ts`. Add `zod` back to dependencies.</violation>
</file>
<file name="knip.config.ts">
<violation number="1" location="knip.config.ts:16">
P2: Removing `lefthook` from `ignoreDependencies` will cause Knip to report it as unused. Lefthook is actively used (see `lefthook.yaml`) but invoked as a binary, not imported in code, so Knip cannot detect its usage.</violation>
</file>
<file name="examples/fetch-tools-debug.ts">
<violation number="1" location="examples/fetch-tools-debug.ts:14">
P2: Documentation mismatch: file is named `fetch-tools-debug.ts` but the run command references `examples/interactive-cli.ts` which doesn't exist.</violation>
</file>
Reply to cubic to teach it or ask questions. Re-run a review with @cubic-dev-ai review this PR
| export async function tryImport<T>(moduleName: string, installHint: string): Promise<T> { | ||
| try { | ||
| return await import(moduleName); | ||
| } catch { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Catch block catches all import errors indiscriminately. If the module is installed but has a syntax error or initialization failure, users will see a misleading "not installed" message. Consider checking for the specific error code (ERR_MODULE_NOT_FOUND) and re-throwing other errors to avoid masking real issues.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/utils/try-import.ts, line 20:
<comment>Catch block catches all import errors indiscriminately. If the module is installed but has a syntax error or initialization failure, users will see a misleading "not installed" message. Consider checking for the specific error code (`ERR_MODULE_NOT_FOUND`) and re-throwing other errors to avoid masking real issues.</comment>
<file context>
@@ -0,0 +1,25 @@
+export async function tryImport<T>(moduleName: string, installHint: string): Promise<T> {
+ try {
+ return await import(moduleName);
+ } catch {
+ throw new StackOneError(
+ `${moduleName} is not installed. Please install it with: ${installHint}`,
</file context>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ryoppippi that seems relevant here. Maybe we could just make the error message more generic. Do we really need this tryImport though?
| "LICENSE" | ||
| "LICENSE", | ||
| "examples/*.ts", | ||
| "!example/*.test.ts" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: Typo in exclusion pattern: !example/*.test.ts should be !examples/*.test.ts (plural). This mismatch means test files will be incorrectly included in the published npm package.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At package.json, line 20:
<comment>Typo in exclusion pattern: `!example/*.test.ts` should be `!examples/*.test.ts` (plural). This mismatch means test files will be incorrectly included in the published npm package.</comment>
<file context>
@@ -15,19 +15,19 @@
- "LICENSE"
+ "LICENSE",
+ "examples/*.ts",
+ "!example/*.test.ts"
],
"scripts": {
</file context>
| "ai": "catalog:peer", | ||
| "openai": "catalog:peer", | ||
| "zod": "catalog:dev" | ||
| "openai": "catalog:peer" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P1: Missing zod dependency. The zod package was removed but is still imported in claude-agent-sdk-integration.ts, tanstack-ai-integration.ts, and claude-agent-sdk-integration.test.ts. Add zod back to dependencies.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At examples/package.json, line 15:
<comment>Missing `zod` dependency. The `zod` package was removed but is still imported in `claude-agent-sdk-integration.ts`, `tanstack-ai-integration.ts`, and `claude-agent-sdk-integration.test.ts`. Add `zod` back to dependencies.</comment>
<file context>
@@ -3,21 +3,20 @@
"ai": "catalog:peer",
- "openai": "catalog:peer",
- "zod": "catalog:dev"
+ "openai": "catalog:peer"
+ },
+ "devDependencies": {
</file context>
| ignore: ['**/*.test.ts', '**/*.spec.ts', '**/*.test-d.ts'], | ||
| ignoreBinaries: ['only-allow'], | ||
| ignoreDependencies: ['@typescript/native-preview', 'lefthook'], | ||
| ignoreDependencies: ['@typescript/native-preview'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Removing lefthook from ignoreDependencies will cause Knip to report it as unused. Lefthook is actively used (see lefthook.yaml) but invoked as a binary, not imported in code, so Knip cannot detect its usage.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At knip.config.ts, line 16:
<comment>Removing `lefthook` from `ignoreDependencies` will cause Knip to report it as unused. Lefthook is actively used (see `lefthook.yaml`) but invoked as a binary, not imported in code, so Knip cannot detect its usage.</comment>
<file context>
@@ -7,13 +7,13 @@ export default {
ignore: ['**/*.test.ts', '**/*.spec.ts', '**/*.test-d.ts'],
ignoreBinaries: ['only-allow'],
- ignoreDependencies: ['@typescript/native-preview', 'lefthook'],
+ ignoreDependencies: ['@typescript/native-preview'],
rules: {
optionalPeerDependencies: 'off',
</file context>
| ignoreDependencies: ['@typescript/native-preview'], | |
| ignoreDependencies: ['@typescript/native-preview', 'lefthook'], |
examples/fetch-tools-debug.ts
Outdated
| * | ||
| * Run with: | ||
| * ```bash | ||
| * npx tsx examples/interactive-cli.ts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Documentation mismatch: file is named fetch-tools-debug.ts but the run command references examples/interactive-cli.ts which doesn't exist.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At examples/fetch-tools-debug.ts, line 14:
<comment>Documentation mismatch: file is named `fetch-tools-debug.ts` but the run command references `examples/interactive-cli.ts` which doesn't exist.</comment>
<file context>
@@ -0,0 +1,297 @@
+ *
+ * Run with:
+ * ```bash
+ * npx tsx examples/interactive-cli.ts
+ * ```
+ */
</file context>
glebedel
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Summary
index.tsexampleFixes #153
Fixes #159
New Integrations
TanStack AI
tanstack-ai-integration.ts: demonstrates StackOne tools with TanStack AIClaude Agent SDK
claude-agent-sdk-integration.ts: demonstrates StackOne tools with Claude Agent SDKcreateSdkMcpServer()with StackOne toolstool()function with Zod schemasDependencies
Added new
examplescatalog in pnpm-workspace.yaml:@tanstack/aiand@tanstack/ai-openaifor TanStack AI integration@anthropic-ai/claude-agent-sdkfor Claude Agent SDK integrationE2E Tests Added
fetch-tools.test.ts: tests tool fetching, filtering, and executionai-sdk-integration.test.ts: tests AI SDK with OpenAI provideropenai-integration.test.ts: tests OpenAI Chat Completions APIopenai-responses-integration.test.ts: tests OpenAI Responses APItanstack-ai-integration.test.ts: tests TanStack AI tool setupclaude-agent-sdk-integration.test.ts: tests Claude Agent SDK tool and MCP server setupTest plan
pnpm test)pnpm lint)pnpm coverage)