-
Notifications
You must be signed in to change notification settings - Fork 0
mastra integration #5
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
Changes from all commits
073155f
d5b49df
d637900
daf2c75
22133d6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| import { Agent } from '@mastra/core/agent'; | ||
| import { AgentRunServer, type AgentRequest } from '../src/server'; | ||
| import { | ||
| MastraConverter, | ||
| type AgentEventItem, | ||
| model, | ||
| toolset, | ||
| } from '../src/integration/mastra'; | ||
|
|
||
| import { logger } from '../src/utils/log'; | ||
|
|
||
| const mastraAgent = new Agent({ | ||
| id: 'run_agent', | ||
| name: 'AgentRun', | ||
| instructions: ` | ||
| 你是一个智能助手,你会帮助用户完成各种任务。你的输出后,必须是返向输出的。 | ||
|
|
||
| 如,用户输入 “你好”,应该输出 “?么的您助帮以可么什有,好您” | ||
| `.trim(), | ||
| model: () => model({ name: 'ohyee-test' }), | ||
| tools: () => toolset({ name: 'start-mcp-time-ggda' }), | ||
| }); | ||
|
|
||
| async function* invokeAgent( | ||
| request: AgentRequest, | ||
| ): AsyncGenerator<AgentEventItem> { | ||
| const converter = new MastraConverter(); | ||
| const mastraStream = await mastraAgent.stream( | ||
| request.messages.map( | ||
| (msg) => | ||
| ({ | ||
| role: msg.role, | ||
| content: msg.content || '', | ||
| }) as any, | ||
| ), | ||
| ); | ||
| for await (const chunk of mastraStream.fullStream) { | ||
| const events = converter.convert(chunk); | ||
|
|
||
| for (const event of events) { | ||
| yield event; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| const server = new AgentRunServer({ | ||
| invokeAgent, | ||
| config: { corsOrigins: ['*'] }, | ||
| }); | ||
|
|
||
| logger.info(` | ||
| curl http://127.0.0.1:9000/openai/v1/chat/completions -X POST \\ | ||
| -H "Content-Type: application/json" \\ | ||
| -d \'{"messages": [{"role": "user", "content": "Hello!"}], "stream": true}\' | ||
|
|
||
| curl http://127.0.0.1:9000/ag-ui/agent -X POST \\ | ||
| -H "Content-Type: application/json" \\ | ||
| -d \'{"messages": [{"role": "user", "content": "Hello!"}]}\' | ||
| `); | ||
|
|
||
| server.start({ port: 9000 }); | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -11,16 +11,58 @@ | |||||
| "types": "./dist/index.d.ts", | ||||||
| "import": "./dist/index.js", | ||||||
| "require": "./dist/index.cjs" | ||||||
| }, | ||||||
| "./agent-runtime": { | ||||||
| "types": "./dist/agent-runtime/index.d.ts", | ||||||
| "import": "./dist/agent-runtime/index.js", | ||||||
| "require": "./dist/agent-runtime/index.cjs" | ||||||
| }, | ||||||
| "./credential": { | ||||||
| "types": "./dist/credential/index.d.ts", | ||||||
| "import": "./dist/credential/index.js", | ||||||
| "require": "./dist/credential/index.cjs" | ||||||
| }, | ||||||
| "./integration": { | ||||||
| "types": "./dist/integration/index.d.ts", | ||||||
| "import": "./dist/integration/index.js", | ||||||
| "require": "./dist/integration/index.cjs" | ||||||
| }, | ||||||
| "./integration/mastra": { | ||||||
| "types": "./dist/integration/mastra/index.d.ts", | ||||||
| "import": "./dist/integration/mastra/index.js", | ||||||
| "require": "./dist/integration/mastra/index.cjs" | ||||||
| }, | ||||||
| "./model": { | ||||||
| "types": "./dist/model/index.d.ts", | ||||||
| "import": "./dist/model/index.js", | ||||||
| "require": "./dist/model/index.cjs" | ||||||
| }, | ||||||
| "./sandbox": { | ||||||
| "types": "./dist/sandbox/index.d.ts", | ||||||
| "import": "./dist/sandbox/index.js", | ||||||
| "require": "./dist/sandbox/index.cjs" | ||||||
| }, | ||||||
| "./server": { | ||||||
| "types": "./dist/server/index.d.ts", | ||||||
| "import": "./dist/server/index.js", | ||||||
| "require": "./dist/server/index.cjs" | ||||||
| }, | ||||||
| "./toolset": { | ||||||
| "types": "./dist/toolset/index.d.ts", | ||||||
| "import": "./dist/toolset/index.js", | ||||||
| "require": "./dist/toolset/index.cjs" | ||||||
| } | ||||||
| }, | ||||||
| "files": [ | ||||||
| "dist", | ||||||
| "README.md" | ||||||
| ], | ||||||
| "scripts": { | ||||||
| "prebuild": "npm run generate-exports", | ||||||
| "build": "tsup", | ||||||
| "build:types": "tsc -p tsconfig.types.json", | ||||||
| "codegen": "npx tsx scripts/codegen.ts", | ||||||
| "generate-exports": "node scripts/generate-exports.mjs", | ||||||
| "format": "prettier --check \"src/**/*.{js,ts,jsx,tsx}\" --write", | ||||||
| "test": "jest", | ||||||
| "test:watch": "jest --watch", | ||||||
|
|
@@ -30,6 +72,7 @@ | |||||
| "typecheck": "tsc --noEmit", | ||||||
| "prepublishOnly": "npm run build", | ||||||
| "example:quick-start": "npx tsx examples/quick-start.ts", | ||||||
| "example:quick-start-with-tools": "npx tsx examples/quick-start-with-tools.ts", | ||||||
| "example:agent-runtime": "npx tsx examples/agent-runtime.ts", | ||||||
| "example:credential": "npx tsx examples/credential.ts", | ||||||
| "example:sandbox": "npx tsx examples/sandbox.ts" | ||||||
|
|
@@ -72,8 +115,17 @@ | |||||
| "uuid": "^9.0.0", | ||||||
| "zod": "^4.2.1" | ||||||
| }, | ||||||
| "peerDependencies": { | ||||||
| "@mastra/core": "*" | ||||||
|
||||||
| "@mastra/core": "*" | |
| "@mastra/core": "^1.0.0" |
OhYee marked this conversation as resolved.
Show resolved
Hide resolved
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| #!/usr/bin/env node | ||
|
|
||
| /** | ||
| * Auto-generate package.json exports for sub-modules | ||
| * | ||
| * This script automatically scans the src directory for index.ts files | ||
| * and generates the corresponding exports in package.json | ||
| * | ||
| * Usage: node scripts/generate-exports.mjs | ||
| */ | ||
|
|
||
| import { readdirSync, statSync, readFileSync, writeFileSync } from 'fs'; | ||
| import { join, resolve, dirname } from 'path'; | ||
| import { fileURLToPath } from 'url'; | ||
|
|
||
| const __filename = fileURLToPath(import.meta.url); | ||
| const __dirname = dirname(__filename); | ||
| const projectRoot = resolve(__dirname, '..'); | ||
| const packageJsonPath = join(projectRoot, 'package.json'); | ||
|
|
||
| // 扫描 src 目录下的所有 index.ts 文件 | ||
| function getSubModules(srcDir) { | ||
| const modules = []; | ||
| const basePath = resolve(srcDir); | ||
|
|
||
| function scanDir(dir, relativePath = '') { | ||
| const items = readdirSync(dir); | ||
|
|
||
| for (const item of items) { | ||
| const fullPath = join(dir, item); | ||
| const stat = statSync(fullPath); | ||
|
|
||
| if (stat.isDirectory()) { | ||
| // 检查是否有 index.ts 文件 | ||
| const indexPath = join(fullPath, 'index.ts'); | ||
| try { | ||
| if (statSync(indexPath).isFile()) { | ||
| const modulePath = relativePath ? `${relativePath}/${item}` : item; | ||
| modules.push(modulePath); | ||
| } | ||
| } catch { | ||
| // index.ts 不存在,继续递归扫描子目录 | ||
| } | ||
|
|
||
| // 递归扫描子目录 | ||
| const newRelativePath = relativePath ? `${relativePath}/${item}` : item; | ||
| scanDir(fullPath, newRelativePath); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // 扫描 src 目录 | ||
| scanDir(basePath); | ||
|
|
||
| // 过滤出用户可能想要导入的模块 | ||
| // 排除一些内部目录,如 api, builtin, adapter, core, protocol, utils | ||
| const excludedDirs = ['api', 'builtin', 'adapter', 'core', 'protocol', 'utils']; | ||
| const mainModules = modules.filter(module => { | ||
| const parts = module.split('/'); | ||
| const lastPart = parts[parts.length - 1]; | ||
| return !excludedDirs.includes(lastPart); | ||
| }); | ||
|
|
||
| return mainModules; | ||
| } | ||
|
|
||
| // 生成 exports 配置 | ||
| function generateExports(modules) { | ||
| const exports = { | ||
| '.': { | ||
| types: './dist/index.d.ts', | ||
| import: './dist/index.js', | ||
| require: './dist/index.cjs' | ||
| } | ||
| }; | ||
|
|
||
| for (const module of modules) { | ||
| exports[`./${module}`] = { | ||
| types: `./dist/${module}/index.d.ts`, | ||
| import: `./dist/${module}/index.js`, | ||
| require: `./dist/${module}/index.cjs` | ||
| }; | ||
| } | ||
|
|
||
| return exports; | ||
| } | ||
|
|
||
| // 更新 package.json | ||
| function updatePackageJson() { | ||
| const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')); | ||
| const subModules = getSubModules('src'); | ||
| const newExports = generateExports(subModules); | ||
|
|
||
| console.log('Found sub-modules:'); | ||
| subModules.forEach(mod => console.log(` - ${mod}`)); | ||
|
|
||
| packageJson.exports = newExports; | ||
|
|
||
| writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n'); | ||
|
|
||
| console.log(`\nUpdated package.json exports with ${subModules.length} sub-modules`); | ||
| } | ||
|
|
||
| // 主函数 | ||
| function main() { | ||
| try { | ||
| updatePackageJson(); | ||
| console.log('✅ Exports generation completed successfully'); | ||
| } catch (error) { | ||
| console.error('❌ Error generating exports:', error); | ||
| process.exit(1); | ||
| } | ||
| } | ||
|
|
||
| main(); |
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 use of 'any' type is overly permissive here. The messages parameter should be typed more strictly according to Mastra's expected message format to ensure type safety and catch errors at compile time.