From df8ee4650027ed42442e5d3a20a4f1dbf9232cba Mon Sep 17 00:00:00 2001 From: Kenji Saito Date: Sun, 9 Nov 2025 13:34:56 +0900 Subject: [PATCH] Add the Claude Agent SDK Sample --- .github/dependabot.yml | 1 + agents/agent-sdk/.gitignore | 8 + agents/agent-sdk/eslint.config.ts | 63 ++++++++ agents/agent-sdk/package.json | 43 ++++++ agents/agent-sdk/src/index.ts | 20 +++ agents/agent-sdk/tsconfig-eslint.json | 10 ++ agents/agent-sdk/tsconfig.json | 44 ++++++ agents/agent-sdk/vitest.config.ts | 40 +++++ pnpm-lock.yaml | 206 +++++++++++++++++++++++++- pnpm-workspace.yaml | 1 + 10 files changed, 430 insertions(+), 6 deletions(-) create mode 100644 agents/agent-sdk/.gitignore create mode 100644 agents/agent-sdk/eslint.config.ts create mode 100644 agents/agent-sdk/package.json create mode 100644 agents/agent-sdk/src/index.ts create mode 100644 agents/agent-sdk/tsconfig-eslint.json create mode 100644 agents/agent-sdk/tsconfig.json create mode 100644 agents/agent-sdk/vitest.config.ts diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7e12845e..5b83d7af 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -24,6 +24,7 @@ updates: - '/common/backend/' - '/agents/agent-mastra/' - '/agents/agent-voltagent/' + - '/agents/agent-sdk/' - '/basic/cdk/' - '/basic/app/' - '/mcp/clients/langgraph-mcp-client/' diff --git a/agents/agent-sdk/.gitignore b/agents/agent-sdk/.gitignore new file mode 100644 index 00000000..8dc8c4aa --- /dev/null +++ b/agents/agent-sdk/.gitignore @@ -0,0 +1,8 @@ +output.txt +node_modules +dist +.mastra +.env.development +.env* +*.db +output.ts diff --git a/agents/agent-sdk/eslint.config.ts b/agents/agent-sdk/eslint.config.ts new file mode 100644 index 00000000..ceaccd49 --- /dev/null +++ b/agents/agent-sdk/eslint.config.ts @@ -0,0 +1,63 @@ +import { defineConfig } from 'eslint/config'; +import eslint from '@eslint/js'; +import stylistic from '@stylistic/eslint-plugin'; +import tseslint from 'typescript-eslint'; +import eslintImport from 'eslint-plugin-import'; + +import { includeIgnoreFile } from '@eslint/compat'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const gitignorePath = path.resolve(__dirname, './.gitignore'); + +export default defineConfig( + includeIgnoreFile(gitignorePath), + { + ignores: [ + '**/*.d.ts', + '*.{js,jsx}', + 'src/tsconfig.json', + 'src/stories', + '**/*.css', + 'node_modules/**/*', + './.next/*', + 'out', + '.storybook', + 'dist', + '.vinxi', + '.output', + ], + }, + eslint.configs.recommended, + ...tseslint.configs.strict, + ...tseslint.configs.stylistic, + { + files: ['src/**/*.{ts,tsx}'], + languageOptions: { + parser: tseslint.parser, + ecmaVersion: 'latest', + sourceType: 'module', + parserOptions: { + projectService: true, + tsconfigRootDir: __dirname, + project: [ + './tsconfig.json', + './tsconfig-eslint.json', + ], + }, + }, + plugins: { + '@stylistic': stylistic, + }, + extends: [eslintImport.flatConfigs.recommended, eslintImport.flatConfigs.typescript], + rules: { + '@stylistic/semi': ['error', 'always'], + '@stylistic/indent': ['error', 2], + '@stylistic/comma-dangle': ['error', 'always-multiline'], + '@stylistic/quotes': ['error', 'single'], + 'import/no-unresolved': 'off', + }, + } +); diff --git a/agents/agent-sdk/package.json b/agents/agent-sdk/package.json new file mode 100644 index 00000000..30dba78b --- /dev/null +++ b/agents/agent-sdk/package.json @@ -0,0 +1,43 @@ +{ + "name": "agent-sdk", + "version": "1.0.0", + "description": "Claude Agent SDK sample implementation for TypeScript", + "main": "dist/index.js", + "type": "module", + "scripts": { + "build": "tsc --build --clean && tsc", + "clean": "tsc --build --clean", + "watch": "tsc -w", + "test": "vitest run --passWithNoTests", + "dev": "tsx src/index.ts", + "lint": "eslint .", + "lint-fix": "eslint . --fix" + }, + "devDependencies": { + "@eslint/compat": "^1.4.1", + "@eslint/js": "^9.39.1", + "@stylistic/eslint-plugin": "^5.5.0", + "@types/node": "^22.19.0", + "@types/uuid": "^10.0.0", + "@vitest/eslint-plugin": "^1.4.1", + "dotenv": "^16.6.1", + "esbuild": "^0.25.12", + "eslint": "^9.39.1", + "eslint-import-resolver-typescript": "^4.4.4", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-promise": "^7.2.1", + "jiti": "^2.6.1", + "tsx": "^4.20.6", + "typescript": "^5.9.3", + "typescript-eslint": "^8.46.3", + "vite": "^7.2.2", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^4.0.8" + }, + "dependencies": { + "@anthropic-ai/claude-agent-sdk": "^0.1.30", + "source-map-support": "^0.5.21", + "uuid": "^13.0.0", + "zod": "^4.1.12" + } +} diff --git a/agents/agent-sdk/src/index.ts b/agents/agent-sdk/src/index.ts new file mode 100644 index 00000000..788d7ffa --- /dev/null +++ b/agents/agent-sdk/src/index.ts @@ -0,0 +1,20 @@ +import { query } from '@anthropic-ai/claude-agent-sdk'; + +(async () => { + const stream = query({ + prompt: + 'Node.js のプログラムでフィボナッチ数列を出力するプログラムを TypeScript 書いて、現在の作業ディレクトリに output.ts という名前で保存してください。ファイルパスは相対パスで ./output.ts としてください。', + options: { + // systemPrompt: '', + allowedTools: ['Write'], + cwd: process.cwd(), + }, + }); + + for await (const message of stream) { + // 実行途中の出力をログ表示 + console.log(message); + } + + console.log('\n処理を完了しました。'); +})(); diff --git a/agents/agent-sdk/tsconfig-eslint.json b/agents/agent-sdk/tsconfig-eslint.json new file mode 100644 index 00000000..ddd75954 --- /dev/null +++ b/agents/agent-sdk/tsconfig-eslint.json @@ -0,0 +1,10 @@ +{ + "extends": ["./tsconfig.json"], + "compilerOptions": { + "noEmit": true + }, + "exclude": [ + "node_modules", + "cdk.out" + ] +} diff --git a/agents/agent-sdk/tsconfig.json b/agents/agent-sdk/tsconfig.json new file mode 100644 index 00000000..e3e20094 --- /dev/null +++ b/agents/agent-sdk/tsconfig.json @@ -0,0 +1,44 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "nodenext", + "lib": [ + "esnext", + "dom" + ], + "moduleResolution": "nodenext", + "moduleDetection": "force", + "resolveJsonModule": true, + "allowJs": true, + "esModuleInterop": true, + "isolatedModules": true, + "declaration": true, + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": false, + "inlineSourceMap": true, + "inlineSources": true, + "experimentalDecorators": true, + "strictPropertyInitialization": false, + "skipLibCheck": true, + "outDir": "./dist", + "typeRoots": [ + "./node_modules", + "./node_modules/@types" + ], + "types": [ + "node" + ] + }, + "exclude": [ + "node_modules", + "cdk.out", + "*.config.*" + ] +} diff --git a/agents/agent-sdk/vitest.config.ts b/agents/agent-sdk/vitest.config.ts new file mode 100644 index 00000000..bef009a9 --- /dev/null +++ b/agents/agent-sdk/vitest.config.ts @@ -0,0 +1,40 @@ +/// +/// + +import { defineConfig } from 'vitest/config'; +import * as dotenv from 'dotenv'; +import { resolve } from 'path'; + +export default defineConfig({ + // モノレポ用の共通設定 + resolve: { + alias: { + // パッケージ間の直接参照 + '@llm-ts-example/common-core': resolve(__dirname, '../../common/core/src'), + '@llm-ts-example/common-backend': resolve(__dirname, '../../common/backend/src') + } + }, + server: { + fs: { + // モノレポ内のファイルアクセスを許可 + allow: ['..'] + } + }, + build: { + target: 'esnext', + rollupOptions: { + // ESModuleとして出力 + output: { + format: 'es' + } + } + }, + root: '.', + test: { + environment: 'node', + globals: true, + isolate: true, + env: dotenv.config({ path: '.env.test' }).parsed, + testTimeout: 30000, + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2a9638f7..633e796e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -99,6 +99,79 @@ importers: specifier: ^8.46.3 version: 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + agents/agent-sdk: + dependencies: + '@anthropic-ai/claude-agent-sdk': + specifier: ^0.1.30 + version: 0.1.30(zod@4.1.12) + source-map-support: + specifier: ^0.5.21 + version: 0.5.21 + uuid: + specifier: ^13.0.0 + version: 13.0.0 + zod: + specifier: ^4.1.12 + version: 4.1.12 + devDependencies: + '@eslint/compat': + specifier: ^1.4.1 + version: 1.4.1(eslint@9.39.1(jiti@2.6.1)) + '@eslint/js': + specifier: ^9.39.1 + version: 9.39.1 + '@stylistic/eslint-plugin': + specifier: ^5.5.0 + version: 5.5.0(eslint@9.39.1(jiti@2.6.1)) + '@types/node': + specifier: ^22.19.0 + version: 22.19.0 + '@types/uuid': + specifier: ^10.0.0 + version: 10.0.0 + '@vitest/eslint-plugin': + specifier: ^1.4.1 + version: 1.4.1(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)(vitest@4.0.8(@types/debug@4.1.12)(@types/node@22.19.0)(jiti@2.6.1)(jsdom@27.1.0)(lightningcss@1.30.1)(tsx@4.20.6)(yaml@2.8.1)) + dotenv: + specifier: ^16.6.1 + version: 16.6.1 + esbuild: + specifier: ^0.25.12 + version: 0.25.12 + eslint: + specifier: ^9.39.1 + version: 9.39.1(jiti@2.6.1) + eslint-import-resolver-typescript: + specifier: ^4.4.4 + version: 4.4.4(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.1(jiti@2.6.1)))(eslint-plugin-import@2.32.0)(eslint@9.39.1(jiti@2.6.1)) + eslint-plugin-import: + specifier: ^2.32.0 + version: 2.32.0(@typescript-eslint/parser@8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.1(jiti@2.6.1)) + eslint-plugin-promise: + specifier: ^7.2.1 + version: 7.2.1(eslint@9.39.1(jiti@2.6.1)) + jiti: + specifier: ^2.6.1 + version: 2.6.1 + tsx: + specifier: ^4.20.6 + version: 4.20.6 + typescript: + specifier: ^5.9.3 + version: 5.9.3 + typescript-eslint: + specifier: ^8.46.3 + version: 8.46.3(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) + vite: + specifier: ^7.2.2 + version: 7.2.2(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(tsx@4.20.6)(yaml@2.8.1) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.9.3)(vite@7.2.2(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.1)(tsx@4.20.6)(yaml@2.8.1)) + vitest: + specifier: ^4.0.8 + version: 4.0.8(@types/debug@4.1.12)(@types/node@22.19.0)(jiti@2.6.1)(jsdom@27.1.0)(lightningcss@1.30.1)(tsx@4.20.6)(yaml@2.8.1) + agents/agent-voltagent: dependencies: '@ai-sdk/amazon-bedrock': @@ -1373,6 +1446,12 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 + '@anthropic-ai/claude-agent-sdk@0.1.30': + resolution: {integrity: sha512-lo1tqxCr2vygagFp6kUMHKSN6AAWlULCskwGKtLB/JcIXy/8H8GsLSKX54anTsvc9mBbCR8wWASdFmiiL9NSKA==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.24.1 + '@anthropic-ai/sdk@0.27.3': resolution: {integrity: sha512-IjLt0gd3L4jlOfilxVXTifn42FnVffMgDC04RJK1KDZpmkBWLv0XC92MVVmkxrFZNS/7l3xWgP/I3nqtX1sQHw==} @@ -2157,6 +2236,67 @@ packages: resolution: {integrity: sha512-u0fmXagywjLAd3apZTV6kRQAHjWl3bNKv5422mQJsM/MZB5YPjx28tjEbpoORh15RuWjYyO/wHZACRWBBkNhbQ==} engines: {node: '>=18.0.0'} + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@inquirer/ansi@1.0.2': resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} engines: {node: '>=18'} @@ -9375,6 +9515,17 @@ snapshots: '@ai-sdk/provider-utils': 3.0.12(zod@4.1.12) zod: 4.1.12 + '@anthropic-ai/claude-agent-sdk@0.1.30(zod@4.1.12)': + dependencies: + zod: 4.1.12 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + '@anthropic-ai/sdk@0.27.3': dependencies: '@types/node': 18.19.130 @@ -10811,6 +10962,49 @@ snapshots: - '@langchain/core' - supports-color + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + '@inquirer/ansi@1.0.2': {} '@inquirer/checkbox@4.3.1(@types/node@22.19.0)': @@ -13548,7 +13742,7 @@ snapshots: '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.19.0 + '@types/node': 24.10.0 '@types/bunyan@1.8.11': dependencies: @@ -13561,7 +13755,7 @@ snapshots: '@types/connect@3.4.38': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.0 '@types/cors@2.8.19': dependencies: @@ -13586,7 +13780,7 @@ snapshots: '@types/express-serve-static-core@5.1.0': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.0 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -13684,16 +13878,16 @@ snapshots: '@types/send@0.17.6': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.19.0 + '@types/node': 24.10.0 '@types/send@1.2.1': dependencies: - '@types/node': 22.19.0 + '@types/node': 24.10.0 '@types/serve-static@1.15.10': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.19.0 + '@types/node': 24.10.0 '@types/send': 0.17.6 '@types/shimmer@1.2.0': {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 22be5bcc..88ac6d0b 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -9,6 +9,7 @@ packages: - ./rag/cdk - ./rag/cdk/function - ./agents/agent-mastra + - ./agents/agent-sdk - ./agents/agent-voltagent - ./mcp/servers/postgresql-http - ./mcp/servers/weather