@mastra/code-sdk 1.2.0-alpha.1 → 1.2.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +175 -0
- package/dist/agents/credential-resolver.d.ts +6 -0
- package/dist/agents/credential-resolver.d.ts.map +1 -1
- package/dist/agents/credential-resolver.js +14 -4
- package/dist/agents/credential-resolver.js.map +1 -1
- package/dist/agents/mastracode-gateway.d.ts.map +1 -1
- package/dist/agents/mastracode-gateway.js +27 -13
- package/dist/agents/mastracode-gateway.js.map +1 -1
- package/dist/agents/model.d.ts +16 -1
- package/dist/agents/model.d.ts.map +1 -1
- package/dist/agents/model.js +27 -6
- package/dist/agents/model.js.map +1 -1
- package/dist/agents/tools.js +1 -1
- package/dist/headless/cli.d.ts.map +1 -1
- package/dist/headless/cli.js +3 -0
- package/dist/headless/cli.js.map +1 -1
- package/dist/headless/flags.js +1 -1
- package/dist/headless/flags.js.map +1 -1
- package/dist/headless/types.d.ts +2 -2
- package/dist/headless/types.d.ts.map +1 -1
- package/dist/headless/types.js +2 -1
- package/dist/headless/types.js.map +1 -1
- package/dist/hooks/executor.d.ts.map +1 -1
- package/dist/hooks/executor.js +1 -0
- package/dist/hooks/executor.js.map +1 -1
- package/dist/hooks/manager.d.ts +9 -2
- package/dist/hooks/manager.d.ts.map +1 -1
- package/dist/hooks/manager.js +19 -3
- package/dist/hooks/manager.js.map +1 -1
- package/dist/hooks/types.d.ts +20 -0
- package/dist/hooks/types.d.ts.map +1 -1
- package/dist/hooks/types.js.map +1 -1
- package/dist/index.d.ts +68 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +179 -64
- package/dist/index.js.map +1 -1
- package/dist/onboarding/settings.d.ts +75 -6
- package/dist/onboarding/settings.d.ts.map +1 -1
- package/dist/onboarding/settings.js +128 -13
- package/dist/onboarding/settings.js.map +1 -1
- package/dist/plugin.d.ts +64 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +3 -1
- package/dist/plugin.js.map +1 -1
- package/dist/plugins/loader.d.ts +7 -3
- package/dist/plugins/loader.d.ts.map +1 -1
- package/dist/plugins/loader.js +53 -1
- package/dist/plugins/loader.js.map +1 -1
- package/dist/plugins/manager.d.ts +36 -2
- package/dist/plugins/manager.d.ts.map +1 -1
- package/dist/plugins/manager.js +74 -2
- package/dist/plugins/manager.js.map +1 -1
- package/dist/plugins/signal-lane.d.ts +58 -0
- package/dist/plugins/signal-lane.d.ts.map +1 -0
- package/dist/plugins/signal-lane.js +166 -0
- package/dist/plugins/signal-lane.js.map +1 -0
- package/dist/plugins/types.d.ts +36 -0
- package/dist/plugins/types.d.ts.map +1 -1
- package/dist/providers/claude-max.d.ts +13 -0
- package/dist/providers/claude-max.d.ts.map +1 -1
- package/dist/providers/claude-max.js +83 -3
- package/dist/providers/claude-max.js.map +1 -1
- package/dist/providers/openai-codex.d.ts +3 -1
- package/dist/providers/openai-codex.d.ts.map +1 -1
- package/dist/providers/openai-codex.js +13 -2
- package/dist/providers/openai-codex.js.map +1 -1
- package/dist/schema.d.ts +11 -5
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +5 -4
- package/dist/schema.js.map +1 -1
- package/package.json +13 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","names":[],"sources":["../../src/plugins/manager.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport { execa } from 'execa';\n\nimport type { MastraCodePluginConfigValue } from '../plugin.js';\nimport { getEntryPackageRoot, installPluginDependenciesForEntry } from './dependencies.js';\nimport { discoverLocalPlugins, installGithubPlugin, installLocalPlugin, NON_INTERACTIVE_GIT_ENV } from './install.js';\nimport type { InstallPluginOptions } from './install.js';\nimport { collectActivePluginTools, isInsideDirectory, loadPlugins, resolvePluginEntryPath } from './loader.js';\nimport { ensureMastraCodePackageLink } from './package-link.js';\nimport { getPluginScopePaths } from './paths.js';\nimport type { PluginPathOptions } from './paths.js';\nimport { loadPluginRegistry, removePluginRecord, savePluginRegistry, setPluginRecord } from './registry.js';\nimport type { LoadedPlugin, PluginScope } from './types.js';\n\nconst GITHUB_PLUGIN_POLL_INTERVAL_MS = 60_000;\n\nfunction gitExecOptions(cwd: string) {\n return { cwd, env: NON_INTERACTIVE_GIT_ENV };\n}\n\nfunction getEntryVersion(entryPath: string): string {\n const stat = fs.statSync(entryPath, { bigint: true });\n return `${stat.mtimeNs}:${stat.size}`;\n}\n\ntype PluginManagerOptions = PluginPathOptions & {\n githubCliPath?: string;\n};\n\nexport class PluginManager {\n private loadedPlugins: LoadedPlugin[] = [];\n private readonly pluginTools: ReturnType<typeof collectActivePluginTools> = {};\n private readonly rawPluginTools: ReturnType<typeof collectActivePluginTools> = {};\n private readonly toolRenderConfigs = new Map<string, NonNullable<LoadedPlugin['renderConfigs']>[string]>();\n private readonly watchedLocalEntries = new Set<string>();\n private readonly localEntryVersions = new Map<string, string>();\n private githubPollTimer: ReturnType<typeof setInterval> | undefined;\n private githubPollInFlight: Promise<boolean> | undefined;\n private reloadInFlight: Promise<LoadedPlugin[]> | undefined;\n private readonly reloadListeners = new Set<(plugins: LoadedPlugin[]) => void | Promise<void>>();\n private readonly githubUpdateListeners = new Set<(pluginNames: string[]) => void | Promise<void>>();\n\n constructor(private readonly options: PluginManagerOptions) {}\n\n onReload(listener: (plugins: LoadedPlugin[]) => void | Promise<void>): () => void {\n this.reloadListeners.add(listener);\n return () => this.reloadListeners.delete(listener);\n }\n\n /** Notified with the display names of GitHub plugins that were updated by the background poll. */\n onGithubPluginsUpdated(listener: (pluginNames: string[]) => void | Promise<void>): () => void {\n this.githubUpdateListeners.add(listener);\n return () => this.githubUpdateListeners.delete(listener);\n }\n\n async reload(): Promise<LoadedPlugin[]> {\n if (this.reloadInFlight) return this.reloadInFlight;\n\n this.reloadInFlight = (async () => {\n this.loadedPlugins = await loadPlugins(this.options);\n this.updateLocalEntryWatchers(this.loadedPlugins);\n this.updateGithubPoller(this.loadedPlugins);\n this.updatePluginRenderConfigs(this.loadedPlugins);\n this.updatePluginTools(collectActivePluginTools(this.loadedPlugins));\n await this.notifyReloadListeners(this.loadedPlugins);\n return this.loadedPlugins;\n })().finally(() => {\n this.reloadInFlight = undefined;\n });\n\n return this.reloadInFlight;\n }\n\n async listPlugins(): Promise<LoadedPlugin[]> {\n if (this.loadedPlugins.length === 0) {\n await this.reload();\n }\n return this.loadedPlugins;\n }\n\n getLoadedPlugins(): LoadedPlugin[] {\n return this.loadedPlugins;\n }\n\n getPluginTools() {\n return this.pluginTools;\n }\n\n getToolRenderConfig(toolName: string) {\n return this.toolRenderConfigs.get(toolName);\n }\n\n getPluginSkillPaths(): string[] {\n return this.loadedPlugins.flatMap(plugin => (plugin.status === 'active' ? (plugin.skillPaths ?? []) : []));\n }\n\n getPluginCommandPaths(): string[] {\n return this.loadedPlugins.flatMap(plugin => (plugin.status === 'active' ? (plugin.commandPaths ?? []) : []));\n }\n\n getPluginInstructions(): string[] {\n return this.loadedPlugins.flatMap(plugin =>\n plugin.status === 'active' && plugin.instructions ? [plugin.instructions] : [],\n );\n }\n\n private async notifyReloadListeners(plugins: LoadedPlugin[]): Promise<void> {\n await Promise.all([...this.reloadListeners].map(listener => Promise.resolve(listener(plugins))));\n }\n\n private updatePluginRenderConfigs(plugins: LoadedPlugin[]): void {\n this.toolRenderConfigs.clear();\n for (const plugin of plugins) {\n if (plugin.status !== 'active') continue;\n for (const [toolName, renderConfig] of Object.entries(plugin.renderConfigs ?? {})) {\n if (!this.toolRenderConfigs.has(toolName)) {\n this.toolRenderConfigs.set(toolName, renderConfig);\n }\n }\n }\n }\n\n private updatePluginTools(nextTools: ReturnType<typeof collectActivePluginTools>): void {\n for (const name of Object.keys(this.rawPluginTools)) {\n if (!(name in nextTools)) {\n delete this.rawPluginTools[name];\n delete this.pluginTools[name];\n }\n }\n\n for (const [name, tool] of Object.entries(nextTools)) {\n this.rawPluginTools[name] = tool;\n if (!this.pluginTools[name]) {\n this.pluginTools[name] = this.createLiveToolProxy(name);\n }\n this.syncLiveToolProxy(name, tool);\n }\n }\n\n private createLiveToolProxy(toolName: string) {\n return {\n execute: async (...args: any[]) => {\n await this.reloadChangedLocalPlugins();\n const latestTool = this.rawPluginTools[toolName];\n if (!latestTool?.execute) {\n throw new Error(`Plugin tool \"${toolName}\" is no longer available`);\n }\n return (latestTool.execute as (...args: any[]) => unknown)(...args);\n },\n } as LoadedPlugin['tools'][string];\n }\n\n private syncLiveToolProxy(toolName: string, tool: LoadedPlugin['tools'][string]): void {\n const proxy = this.pluginTools[toolName];\n if (!proxy) return;\n const mutableProxy = proxy as unknown as Record<string, unknown>;\n for (const key of Object.keys(mutableProxy)) {\n delete mutableProxy[key];\n }\n Object.assign(proxy, tool);\n proxy.execute = this.createLiveToolProxy(toolName).execute;\n }\n\n private async reloadChangedLocalPlugins(): Promise<void> {\n for (const plugin of this.loadedPlugins) {\n if (plugin.source !== 'local' || plugin.status !== 'active') continue;\n const entryPath = resolvePluginEntryPath(plugin, this.options);\n const currentVersion = getEntryVersion(entryPath);\n if (this.localEntryVersions.get(entryPath) !== currentVersion) {\n await this.reload();\n return;\n }\n }\n }\n\n private updateLocalEntryWatchers(plugins: LoadedPlugin[]): void {\n const nextEntries = new Set<string>();\n for (const plugin of plugins) {\n if (plugin.source !== 'local' || plugin.status !== 'active') continue;\n let entryPath: string;\n let entryVersion: string;\n try {\n entryPath = resolvePluginEntryPath(plugin, this.options);\n entryVersion = getEntryVersion(entryPath);\n } catch {\n continue;\n }\n nextEntries.add(entryPath);\n this.localEntryVersions.set(entryPath, entryVersion);\n if (this.watchedLocalEntries.has(entryPath)) continue;\n\n const watcher = fs.watchFile(entryPath, { interval: 500 }, (current, previous) => {\n if (current.mtimeMs === previous.mtimeMs) return;\n void this.reload().catch(() => undefined);\n });\n watcher.unref?.();\n this.watchedLocalEntries.add(entryPath);\n }\n\n for (const entryPath of this.watchedLocalEntries) {\n if (nextEntries.has(entryPath)) continue;\n fs.unwatchFile(entryPath);\n this.watchedLocalEntries.delete(entryPath);\n this.localEntryVersions.delete(entryPath);\n }\n }\n\n private updateGithubPoller(plugins: LoadedPlugin[]): void {\n const hasGithubPlugin = plugins.some(\n plugin => plugin.source === 'github' && plugin.status !== 'inactive' && plugin.status !== 'blocked',\n );\n if (hasGithubPlugin && !this.githubPollTimer) {\n this.githubPollTimer = setInterval(() => {\n void this.pollGithubSourcesForUpdates().catch(() => undefined);\n }, GITHUB_PLUGIN_POLL_INTERVAL_MS);\n this.githubPollTimer.unref?.();\n }\n if (!hasGithubPlugin && this.githubPollTimer) {\n clearInterval(this.githubPollTimer);\n this.githubPollTimer = undefined;\n }\n }\n\n async pollGithubSourcesForUpdates(): Promise<boolean> {\n if (this.githubPollInFlight) return this.githubPollInFlight;\n this.githubPollInFlight = this.pollGithubSourcesForUpdatesOnce().finally(() => {\n this.githubPollInFlight = undefined;\n });\n return this.githubPollInFlight;\n }\n\n private async pollGithubSourcesForUpdatesOnce(): Promise<boolean> {\n const changedCheckouts = new Set<string>();\n const seen = new Set<string>();\n for (const plugin of this.loadedPlugins) {\n if (plugin.source !== 'github' || plugin.status === 'inactive' || plugin.status === 'blocked') continue;\n const checkoutPath = this.resolvePluginSourcePath(plugin);\n if (seen.has(checkoutPath) || !fs.existsSync(path.join(checkoutPath, '.git'))) continue;\n seen.add(checkoutPath);\n\n const before = await this.readGitHead(checkoutPath);\n const checkoutChanged = await this.refreshGithubCheckout(plugin, checkoutPath, before);\n const after = await this.readGitHead(checkoutPath);\n if (checkoutChanged || before !== after) changedCheckouts.add(checkoutPath);\n }\n\n if (changedCheckouts.size === 0) return false;\n\n await this.reload();\n // Derive names from the reloaded state so a manifest display-name change reports the new name.\n // Multiple plugins can share one checkout — report every plugin whose source changed.\n const updatedPluginNames = this.loadedPlugins\n .filter(\n plugin =>\n plugin.source === 'github' &&\n plugin.status !== 'inactive' &&\n plugin.status !== 'blocked' &&\n changedCheckouts.has(this.resolvePluginSourcePath(plugin)),\n )\n .map(plugin => plugin.name ?? plugin.id);\n await this.notifyGithubUpdateListeners(updatedPluginNames);\n return true;\n }\n\n private async notifyGithubUpdateListeners(pluginNames: string[]): Promise<void> {\n await Promise.all([...this.githubUpdateListeners].map(listener => Promise.resolve(listener(pluginNames))));\n }\n\n private async refreshGithubCheckout(\n plugin: LoadedPlugin,\n checkoutPath: string,\n currentHead: string,\n ): Promise<boolean> {\n await execa('git', ['fetch', 'origin'], gitExecOptions(checkoutPath));\n const upstream = await this.resolveGitUpstream(checkoutPath, plugin.ref);\n if (!upstream) return false;\n const [localOnly, remoteOnly] = await this.readGitAheadBehind(checkoutPath, upstream);\n const hasLocalChanges = await this.hasGitWorkingTreeChanges(checkoutPath);\n\n if (localOnly > 0 || hasLocalChanges) {\n await this.backupGitCheckout(checkoutPath, currentHead, hasLocalChanges);\n }\n\n if (remoteOnly > 0 || localOnly > 0 || hasLocalChanges) {\n await execa('git', ['reset', '--hard', upstream], gitExecOptions(checkoutPath));\n try {\n await installPluginDependenciesForEntry(checkoutPath, plugin.entry);\n ensureMastraCodePackageLink(getEntryPackageRoot(checkoutPath, plugin.entry));\n } catch (error) {\n await execa('git', ['reset', '--hard', currentHead], gitExecOptions(checkoutPath));\n throw error;\n }\n return true;\n }\n\n return false;\n }\n\n private async backupGitCheckout(\n checkoutPath: string,\n currentHead: string,\n includeWorkingTree: boolean,\n ): Promise<void> {\n const backupBranch = this.createGitBackupBranchName(currentHead);\n\n if (includeWorkingTree) {\n const currentBranch = await this.readGitCurrentBranch(checkoutPath);\n await execa('git', ['switch', '-c', backupBranch], gitExecOptions(checkoutPath));\n await execa('git', ['add', '-A'], gitExecOptions(checkoutPath));\n const hasStagedChanges = await this.hasGitStagedChanges(checkoutPath);\n if (hasStagedChanges) {\n await execa(\n 'git',\n [\n '-c',\n 'user.name=Mastra Code',\n '-c',\n 'user.email=noreply@mastra.ai',\n 'commit',\n '-m',\n 'chore: backup local plugin checkout changes',\n ],\n gitExecOptions(checkoutPath),\n );\n }\n await this.restoreGitCheckout(checkoutPath, currentBranch, currentHead);\n return;\n }\n\n await execa('git', ['branch', backupBranch, 'HEAD'], gitExecOptions(checkoutPath));\n }\n\n private async resolveGitUpstream(cwd: string, installedRef?: string): Promise<string | undefined> {\n try {\n const { stdout } = await execa(\n 'git',\n ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'],\n gitExecOptions(cwd),\n );\n return stdout.trim();\n } catch {\n return installedRef ? undefined : 'origin/main';\n }\n }\n\n private async readGitAheadBehind(cwd: string, upstream: string): Promise<[number, number]> {\n const { stdout } = await execa(\n 'git',\n ['rev-list', '--left-right', '--count', `HEAD...${upstream}`],\n gitExecOptions(cwd),\n );\n const [ahead = '0', behind = '0'] = stdout.trim().split(/\\s+/);\n return [Number(ahead) || 0, Number(behind) || 0];\n }\n\n private async hasGitWorkingTreeChanges(cwd: string): Promise<boolean> {\n const { stdout } = await execa('git', ['status', '--porcelain'], gitExecOptions(cwd));\n return stdout.trim().length > 0;\n }\n\n private async hasGitStagedChanges(cwd: string): Promise<boolean> {\n try {\n await execa('git', ['diff', '--cached', '--quiet'], gitExecOptions(cwd));\n return false;\n } catch {\n return true;\n }\n }\n\n private async restoreGitCheckout(cwd: string, branch: string | undefined, fallbackHead: string): Promise<void> {\n if (branch) {\n await execa('git', ['switch', branch], gitExecOptions(cwd));\n return;\n }\n await execa('git', ['checkout', fallbackHead], gitExecOptions(cwd));\n }\n\n private async readGitCurrentBranch(cwd: string): Promise<string | undefined> {\n const { stdout } = await execa('git', ['branch', '--show-current'], gitExecOptions(cwd));\n const branch = stdout.trim();\n return branch.length > 0 ? branch : undefined;\n }\n\n private createGitBackupBranchName(currentHead: string): string {\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n return `mastracode/plugin-backup/${timestamp}-${currentHead.slice(0, 8)}`;\n }\n\n private resolvePluginSourcePath(plugin: LoadedPlugin): string {\n const paths = getPluginScopePaths(plugin.scope, this.options);\n return path.isAbsolute(plugin.path) ? plugin.path : path.join(paths.root, plugin.path);\n }\n\n private async readGitHead(cwd: string): Promise<string> {\n const { stdout } = await execa('git', ['rev-parse', 'HEAD'], gitExecOptions(cwd));\n return stdout.trim();\n }\n\n discoverLocal(searchRoot = '.'): ReturnType<typeof discoverLocalPlugins> {\n return discoverLocalPlugins(searchRoot, this.options);\n }\n\n async installLocal(\n localPath: string,\n scope: PluginScope,\n options: Pick<InstallPluginOptions, 'entry'> = {},\n ): Promise<string> {\n const id = await installLocalPlugin(localPath, scope, { ...this.options, ...options });\n await this.reload();\n return id;\n }\n\n async installGithub(\n url: string,\n scope: PluginScope,\n options: Pick<InstallPluginOptions, 'entry' | 'ref' | 'onOutput' | 'signal'> = {},\n ): Promise<string> {\n const id = await installGithubPlugin(url, scope, { ...this.options, ...options });\n await this.reload();\n return id;\n }\n\n async setEnabled(pluginId: string, scope: PluginScope, enabled: boolean): Promise<void> {\n const paths = getPluginScopePaths(scope, this.options);\n const registry = loadPluginRegistry(paths.registryPath);\n const record = registry.plugins[pluginId];\n if (!record) {\n throw new Error(`Plugin \"${pluginId}\" is not installed in ${scope} scope`);\n }\n savePluginRegistry(paths.registryPath, setPluginRecord(registry, pluginId, { ...record, enabled }));\n await this.reload();\n }\n\n async setConfigValue(\n pluginId: string,\n scope: PluginScope,\n key: string,\n value: MastraCodePluginConfigValue,\n ): Promise<void> {\n const paths = getPluginScopePaths(scope, this.options);\n const registry = loadPluginRegistry(paths.registryPath);\n const record = registry.plugins[pluginId];\n if (!record) {\n throw new Error(`Plugin \"${pluginId}\" is not installed in ${scope} scope`);\n }\n const config = { ...(record.config ?? {}) };\n if (value === undefined || value === '') {\n delete config[key];\n } else {\n config[key] = value;\n }\n const nextRecord = { ...record, config: Object.keys(config).length > 0 ? config : undefined };\n savePluginRegistry(paths.registryPath, setPluginRecord(registry, pluginId, nextRecord));\n await this.reload();\n }\n\n async uninstall(pluginId: string, scope: PluginScope): Promise<void> {\n const paths = getPluginScopePaths(scope, this.options);\n const registry = loadPluginRegistry(paths.registryPath);\n const record = registry.plugins[pluginId];\n if (!record) {\n throw new Error(`Plugin \"${pluginId}\" is not installed in ${scope} scope`);\n }\n\n savePluginRegistry(paths.registryPath, removePluginRecord(registry, pluginId));\n if (record.source === 'github') {\n const checkoutPath = path.resolve(\n path.isAbsolute(record.path) ? record.path : path.join(paths.root, record.path),\n );\n const githubSourcesPath = path.resolve(paths.sourcesPath, 'github');\n if (isInsideDirectory(checkoutPath, githubSourcesPath)) {\n fs.rmSync(checkoutPath, { recursive: true, force: true });\n }\n }\n await this.reload();\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"manager.js","names":[],"sources":["../../src/plugins/manager.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport type { SignalProvider } from '@mastra/core/signals';\nimport { execa } from 'execa';\n\nimport type { MastraCodePluginConfigValue, MastraCodePluginRuntime } from '../plugin.js';\nimport { getEntryPackageRoot, installPluginDependenciesForEntry } from './dependencies.js';\nimport { discoverLocalPlugins, installGithubPlugin, installLocalPlugin, NON_INTERACTIVE_GIT_ENV } from './install.js';\nimport type { InstallPluginOptions } from './install.js';\nimport { collectActivePluginTools, isInsideDirectory, loadPlugins, resolvePluginEntryPath } from './loader.js';\nimport { ensureMastraCodePackageLink } from './package-link.js';\nimport { getPluginScopePaths } from './paths.js';\nimport type { PluginPathOptions } from './paths.js';\nimport { loadPluginRegistry, removePluginRecord, savePluginRegistry, setPluginRecord } from './registry.js';\nimport type { LoadedPlugin, PluginContribution, PluginProcessorEntries, PluginScope } from './types.js';\n\nconst GITHUB_PLUGIN_POLL_INTERVAL_MS = 60_000;\n\nfunction gitExecOptions(cwd: string) {\n return { cwd, env: NON_INTERACTIVE_GIT_ENV };\n}\n\nfunction getEntryVersion(entryPath: string): string {\n const stat = fs.statSync(entryPath, { bigint: true });\n return `${stat.mtimeNs}:${stat.size}`;\n}\n\ntype PluginManagerOptions = PluginPathOptions & {\n githubCliPath?: string;\n /**\n * Lazy accessors for Mastra Code's runtime, handed to plugin field resolvers on\n * every load and reload.\n */\n runtime?: MastraCodePluginRuntime;\n};\n\nexport class PluginManager {\n private loadedPlugins: LoadedPlugin[] = [];\n private readonly pluginTools: ReturnType<typeof collectActivePluginTools> = {};\n private readonly rawPluginTools: ReturnType<typeof collectActivePluginTools> = {};\n private readonly toolRenderConfigs = new Map<string, NonNullable<LoadedPlugin['renderConfigs']>[string]>();\n private readonly watchedLocalEntries = new Set<string>();\n private readonly localEntryVersions = new Map<string, string>();\n /** Last known git HEAD per GitHub checkout, kept current by the poller. */\n private readonly githubCheckoutHeads = new Map<string, string>();\n private githubPollTimer: ReturnType<typeof setInterval> | undefined;\n private githubPollInFlight: Promise<boolean> | undefined;\n private reloadInFlight: Promise<LoadedPlugin[]> | undefined;\n private readonly reloadListeners = new Set<(plugins: LoadedPlugin[]) => void | Promise<void>>();\n private readonly githubUpdateListeners = new Set<(pluginNames: string[]) => void | Promise<void>>();\n private runtime: MastraCodePluginRuntime | undefined;\n\n constructor(private readonly options: PluginManagerOptions) {\n this.runtime = options.runtime;\n }\n\n /**\n * Publish (or replace) the runtime accessors handed to plugin field resolvers.\n * Takes effect on the next load or reload. `createMastraCode` calls this for\n * every manager it uses — including an injected one — so a manager constructed\n * without a runtime still exposes `getController`/`getActiveSession` to plugins.\n * A manager shared across controllers sees the most recent controller's accessors.\n */\n setRuntime(runtime: MastraCodePluginRuntime): void {\n this.runtime = runtime;\n }\n\n onReload(listener: (plugins: LoadedPlugin[]) => void | Promise<void>): () => void {\n this.reloadListeners.add(listener);\n return () => this.reloadListeners.delete(listener);\n }\n\n /** Notified with the display names of GitHub plugins that were updated by the background poll. */\n onGithubPluginsUpdated(listener: (pluginNames: string[]) => void | Promise<void>): () => void {\n this.githubUpdateListeners.add(listener);\n return () => this.githubUpdateListeners.delete(listener);\n }\n\n async reload(): Promise<LoadedPlugin[]> {\n if (this.reloadInFlight) return this.reloadInFlight;\n\n this.reloadInFlight = (async () => {\n this.loadedPlugins = await loadPlugins({ ...this.options, runtime: this.runtime });\n await this.stampLoadedPlugins(this.loadedPlugins);\n this.updateLocalEntryWatchers(this.loadedPlugins);\n this.updateGithubPoller(this.loadedPlugins);\n this.updatePluginRenderConfigs(this.loadedPlugins);\n this.updatePluginTools(collectActivePluginTools(this.loadedPlugins));\n await this.notifyReloadListeners(this.loadedPlugins);\n return this.loadedPlugins;\n })().finally(() => {\n this.reloadInFlight = undefined;\n });\n\n return this.reloadInFlight;\n }\n\n async listPlugins(): Promise<LoadedPlugin[]> {\n if (this.loadedPlugins.length === 0) {\n await this.reload();\n }\n return this.loadedPlugins;\n }\n\n getLoadedPlugins(): LoadedPlugin[] {\n return this.loadedPlugins;\n }\n\n getPluginTools() {\n return this.pluginTools;\n }\n\n getToolRenderConfig(toolName: string) {\n return this.toolRenderConfigs.get(toolName);\n }\n\n getPluginSkillPaths(): string[] {\n return this.loadedPlugins.flatMap(plugin => (plugin.status === 'active' ? (plugin.skillPaths ?? []) : []));\n }\n\n getPluginCommandPaths(): string[] {\n return this.loadedPlugins.flatMap(plugin => (plugin.status === 'active' ? (plugin.commandPaths ?? []) : []));\n }\n\n getPluginInstructions(): string[] {\n return this.loadedPlugins.flatMap(plugin =>\n plugin.status === 'active' && plugin.instructions ? [plugin.instructions] : [],\n );\n }\n\n /**\n * Processors contributed by active plugins, tagged with the plugin that owns\n * each one. Reads already-resolved state — no filesystem access — because the\n * agent's processor lanes call this before every request.\n */\n getPluginProcessors(): PluginProcessorEntries {\n return {\n input: this.collectActive(plugin => plugin.processors?.input ?? []),\n output: this.collectActive(plugin => plugin.processors?.output ?? []),\n };\n }\n\n /** Signal providers contributed by active plugins, tagged with their owning plugin. */\n getPluginSignalProviders(): PluginContribution<SignalProvider<string>>[] {\n return this.collectActive(plugin => plugin.signalProviders ?? []);\n }\n\n private collectActive<TValue>(select: (plugin: LoadedPlugin) => TValue[]): PluginContribution<TValue>[] {\n return this.loadedPlugins.flatMap(plugin =>\n plugin.status === 'active'\n ? select(plugin).map(value => ({ pluginId: plugin.id, versionStamp: plugin.versionStamp ?? '', value }))\n : [],\n );\n }\n\n private async notifyReloadListeners(plugins: LoadedPlugin[]): Promise<void> {\n await Promise.all([...this.reloadListeners].map(listener => Promise.resolve(listener(plugins))));\n }\n\n /**\n * Stamps each plugin with a value that changes when its contributions should\n * be rebuilt. Runs on every reload, so it stays off the network: GitHub heads\n * come from the cache the poller keeps current and cost one `git rev-parse`\n * per checkout the first time it is seen.\n */\n private async stampLoadedPlugins(plugins: LoadedPlugin[]): Promise<void> {\n for (const plugin of plugins) {\n plugin.versionStamp = [\n plugin.status,\n await this.readSourceStamp(plugin),\n JSON.stringify(plugin.configValues ?? {}),\n ].join('|');\n }\n }\n\n private async readSourceStamp(plugin: LoadedPlugin): Promise<string> {\n try {\n if (plugin.source === 'github') {\n const checkoutPath = this.resolvePluginSourcePath(plugin);\n let head = this.githubCheckoutHeads.get(checkoutPath);\n if (head === undefined) {\n head = await this.readGitHead(checkoutPath);\n this.githubCheckoutHeads.set(checkoutPath, head);\n }\n return head;\n }\n return getEntryVersion(resolvePluginEntryPath(plugin, this.options));\n } catch {\n // A plugin that failed to load has no readable source. Its stamp is then\n // status + config, which is enough to notice when it starts working.\n return '';\n }\n }\n\n private updatePluginRenderConfigs(plugins: LoadedPlugin[]): void {\n this.toolRenderConfigs.clear();\n for (const plugin of plugins) {\n if (plugin.status !== 'active') continue;\n for (const [toolName, renderConfig] of Object.entries(plugin.renderConfigs ?? {})) {\n if (!this.toolRenderConfigs.has(toolName)) {\n this.toolRenderConfigs.set(toolName, renderConfig);\n }\n }\n }\n }\n\n private updatePluginTools(nextTools: ReturnType<typeof collectActivePluginTools>): void {\n for (const name of Object.keys(this.rawPluginTools)) {\n if (!(name in nextTools)) {\n delete this.rawPluginTools[name];\n delete this.pluginTools[name];\n }\n }\n\n for (const [name, tool] of Object.entries(nextTools)) {\n this.rawPluginTools[name] = tool;\n if (!this.pluginTools[name]) {\n this.pluginTools[name] = this.createLiveToolProxy(name);\n }\n this.syncLiveToolProxy(name, tool);\n }\n }\n\n private createLiveToolProxy(toolName: string) {\n return {\n execute: async (...args: any[]) => {\n await this.reloadChangedLocalPlugins();\n const latestTool = this.rawPluginTools[toolName];\n if (!latestTool?.execute) {\n throw new Error(`Plugin tool \"${toolName}\" is no longer available`);\n }\n return (latestTool.execute as (...args: any[]) => unknown)(...args);\n },\n } as LoadedPlugin['tools'][string];\n }\n\n private syncLiveToolProxy(toolName: string, tool: LoadedPlugin['tools'][string]): void {\n const proxy = this.pluginTools[toolName];\n if (!proxy) return;\n const mutableProxy = proxy as unknown as Record<string, unknown>;\n for (const key of Object.keys(mutableProxy)) {\n delete mutableProxy[key];\n }\n Object.assign(proxy, tool);\n proxy.execute = this.createLiveToolProxy(toolName).execute;\n }\n\n private async reloadChangedLocalPlugins(): Promise<void> {\n for (const plugin of this.loadedPlugins) {\n if (plugin.source !== 'local' || plugin.status !== 'active') continue;\n const entryPath = resolvePluginEntryPath(plugin, this.options);\n const currentVersion = getEntryVersion(entryPath);\n if (this.localEntryVersions.get(entryPath) !== currentVersion) {\n await this.reload();\n return;\n }\n }\n }\n\n private updateLocalEntryWatchers(plugins: LoadedPlugin[]): void {\n const nextEntries = new Set<string>();\n for (const plugin of plugins) {\n if (plugin.source !== 'local' || plugin.status !== 'active') continue;\n let entryPath: string;\n let entryVersion: string;\n try {\n entryPath = resolvePluginEntryPath(plugin, this.options);\n entryVersion = getEntryVersion(entryPath);\n } catch {\n continue;\n }\n nextEntries.add(entryPath);\n this.localEntryVersions.set(entryPath, entryVersion);\n if (this.watchedLocalEntries.has(entryPath)) continue;\n\n const watcher = fs.watchFile(entryPath, { interval: 500 }, (current, previous) => {\n if (current.mtimeMs === previous.mtimeMs) return;\n void this.reload().catch(() => undefined);\n });\n watcher.unref?.();\n this.watchedLocalEntries.add(entryPath);\n }\n\n for (const entryPath of this.watchedLocalEntries) {\n if (nextEntries.has(entryPath)) continue;\n fs.unwatchFile(entryPath);\n this.watchedLocalEntries.delete(entryPath);\n this.localEntryVersions.delete(entryPath);\n }\n }\n\n private updateGithubPoller(plugins: LoadedPlugin[]): void {\n const hasGithubPlugin = plugins.some(\n plugin => plugin.source === 'github' && plugin.status !== 'inactive' && plugin.status !== 'blocked',\n );\n if (hasGithubPlugin && !this.githubPollTimer) {\n this.githubPollTimer = setInterval(() => {\n void this.pollGithubSourcesForUpdates().catch(() => undefined);\n }, GITHUB_PLUGIN_POLL_INTERVAL_MS);\n this.githubPollTimer.unref?.();\n }\n if (!hasGithubPlugin && this.githubPollTimer) {\n clearInterval(this.githubPollTimer);\n this.githubPollTimer = undefined;\n }\n }\n\n async pollGithubSourcesForUpdates(): Promise<boolean> {\n if (this.githubPollInFlight) return this.githubPollInFlight;\n this.githubPollInFlight = this.pollGithubSourcesForUpdatesOnce().finally(() => {\n this.githubPollInFlight = undefined;\n });\n return this.githubPollInFlight;\n }\n\n private async pollGithubSourcesForUpdatesOnce(): Promise<boolean> {\n const changedCheckouts = new Set<string>();\n const seen = new Set<string>();\n for (const plugin of this.loadedPlugins) {\n if (plugin.source !== 'github' || plugin.status === 'inactive' || plugin.status === 'blocked') continue;\n const checkoutPath = this.resolvePluginSourcePath(plugin);\n if (seen.has(checkoutPath) || !fs.existsSync(path.join(checkoutPath, '.git'))) continue;\n seen.add(checkoutPath);\n\n const before = await this.readGitHead(checkoutPath);\n const checkoutChanged = await this.refreshGithubCheckout(plugin, checkoutPath, before);\n const after = await this.readGitHead(checkoutPath);\n // Feed the cache before reloading: the stamp is computed during reload and\n // has to see the new head, or a real update would look unchanged.\n this.githubCheckoutHeads.set(checkoutPath, after);\n if (checkoutChanged || before !== after) changedCheckouts.add(checkoutPath);\n }\n\n if (changedCheckouts.size === 0) return false;\n\n await this.reload();\n // Derive names from the reloaded state so a manifest display-name change reports the new name.\n // Multiple plugins can share one checkout — report every plugin whose source changed.\n const updatedPluginNames = this.loadedPlugins\n .filter(\n plugin =>\n plugin.source === 'github' &&\n plugin.status !== 'inactive' &&\n plugin.status !== 'blocked' &&\n changedCheckouts.has(this.resolvePluginSourcePath(plugin)),\n )\n .map(plugin => plugin.name ?? plugin.id);\n await this.notifyGithubUpdateListeners(updatedPluginNames);\n return true;\n }\n\n private async notifyGithubUpdateListeners(pluginNames: string[]): Promise<void> {\n await Promise.all([...this.githubUpdateListeners].map(listener => Promise.resolve(listener(pluginNames))));\n }\n\n private async refreshGithubCheckout(\n plugin: LoadedPlugin,\n checkoutPath: string,\n currentHead: string,\n ): Promise<boolean> {\n await execa('git', ['fetch', 'origin'], gitExecOptions(checkoutPath));\n const upstream = await this.resolveGitUpstream(checkoutPath, plugin.ref);\n if (!upstream) return false;\n const [localOnly, remoteOnly] = await this.readGitAheadBehind(checkoutPath, upstream);\n const hasLocalChanges = await this.hasGitWorkingTreeChanges(checkoutPath);\n\n if (localOnly > 0 || hasLocalChanges) {\n await this.backupGitCheckout(checkoutPath, currentHead, hasLocalChanges);\n }\n\n if (remoteOnly > 0 || localOnly > 0 || hasLocalChanges) {\n await execa('git', ['reset', '--hard', upstream], gitExecOptions(checkoutPath));\n try {\n await installPluginDependenciesForEntry(checkoutPath, plugin.entry);\n ensureMastraCodePackageLink(getEntryPackageRoot(checkoutPath, plugin.entry));\n } catch (error) {\n await execa('git', ['reset', '--hard', currentHead], gitExecOptions(checkoutPath));\n throw error;\n }\n return true;\n }\n\n return false;\n }\n\n private async backupGitCheckout(\n checkoutPath: string,\n currentHead: string,\n includeWorkingTree: boolean,\n ): Promise<void> {\n const backupBranch = this.createGitBackupBranchName(currentHead);\n\n if (includeWorkingTree) {\n const currentBranch = await this.readGitCurrentBranch(checkoutPath);\n await execa('git', ['switch', '-c', backupBranch], gitExecOptions(checkoutPath));\n await execa('git', ['add', '-A'], gitExecOptions(checkoutPath));\n const hasStagedChanges = await this.hasGitStagedChanges(checkoutPath);\n if (hasStagedChanges) {\n await execa(\n 'git',\n [\n '-c',\n 'user.name=Mastra Code',\n '-c',\n 'user.email=noreply@mastra.ai',\n 'commit',\n '-m',\n 'chore: backup local plugin checkout changes',\n ],\n gitExecOptions(checkoutPath),\n );\n }\n await this.restoreGitCheckout(checkoutPath, currentBranch, currentHead);\n return;\n }\n\n await execa('git', ['branch', backupBranch, 'HEAD'], gitExecOptions(checkoutPath));\n }\n\n private async resolveGitUpstream(cwd: string, installedRef?: string): Promise<string | undefined> {\n try {\n const { stdout } = await execa(\n 'git',\n ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{u}'],\n gitExecOptions(cwd),\n );\n return stdout.trim();\n } catch {\n return installedRef ? undefined : 'origin/main';\n }\n }\n\n private async readGitAheadBehind(cwd: string, upstream: string): Promise<[number, number]> {\n const { stdout } = await execa(\n 'git',\n ['rev-list', '--left-right', '--count', `HEAD...${upstream}`],\n gitExecOptions(cwd),\n );\n const [ahead = '0', behind = '0'] = stdout.trim().split(/\\s+/);\n return [Number(ahead) || 0, Number(behind) || 0];\n }\n\n private async hasGitWorkingTreeChanges(cwd: string): Promise<boolean> {\n const { stdout } = await execa('git', ['status', '--porcelain'], gitExecOptions(cwd));\n return stdout.trim().length > 0;\n }\n\n private async hasGitStagedChanges(cwd: string): Promise<boolean> {\n try {\n await execa('git', ['diff', '--cached', '--quiet'], gitExecOptions(cwd));\n return false;\n } catch {\n return true;\n }\n }\n\n private async restoreGitCheckout(cwd: string, branch: string | undefined, fallbackHead: string): Promise<void> {\n if (branch) {\n await execa('git', ['switch', branch], gitExecOptions(cwd));\n return;\n }\n await execa('git', ['checkout', fallbackHead], gitExecOptions(cwd));\n }\n\n private async readGitCurrentBranch(cwd: string): Promise<string | undefined> {\n const { stdout } = await execa('git', ['branch', '--show-current'], gitExecOptions(cwd));\n const branch = stdout.trim();\n return branch.length > 0 ? branch : undefined;\n }\n\n private createGitBackupBranchName(currentHead: string): string {\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n return `mastracode/plugin-backup/${timestamp}-${currentHead.slice(0, 8)}`;\n }\n\n private resolvePluginSourcePath(plugin: LoadedPlugin): string {\n const paths = getPluginScopePaths(plugin.scope, this.options);\n // Normalized so cache keys derived here match the `path.resolve`-normalized\n // key that `uninstall` deletes with.\n return path.resolve(path.isAbsolute(plugin.path) ? plugin.path : path.join(paths.root, plugin.path));\n }\n\n private async readGitHead(cwd: string): Promise<string> {\n const { stdout } = await execa('git', ['rev-parse', 'HEAD'], gitExecOptions(cwd));\n return stdout.trim();\n }\n\n discoverLocal(searchRoot = '.'): ReturnType<typeof discoverLocalPlugins> {\n return discoverLocalPlugins(searchRoot, this.options);\n }\n\n async installLocal(\n localPath: string,\n scope: PluginScope,\n options: Pick<InstallPluginOptions, 'entry'> = {},\n ): Promise<string> {\n const id = await installLocalPlugin(localPath, scope, { ...this.options, ...options });\n await this.reload();\n return id;\n }\n\n async installGithub(\n url: string,\n scope: PluginScope,\n options: Pick<InstallPluginOptions, 'entry' | 'ref' | 'onOutput' | 'signal'> = {},\n ): Promise<string> {\n const id = await installGithubPlugin(url, scope, { ...this.options, ...options });\n // Installing over an existing checkout replaces it at the same path, so the\n // cached head would make a genuinely different commit stamp as unchanged and\n // leave the previous signal providers running.\n this.githubCheckoutHeads.clear();\n await this.reload();\n return id;\n }\n\n async setEnabled(pluginId: string, scope: PluginScope, enabled: boolean): Promise<void> {\n const paths = getPluginScopePaths(scope, this.options);\n const registry = loadPluginRegistry(paths.registryPath);\n const record = registry.plugins[pluginId];\n if (!record) {\n throw new Error(`Plugin \"${pluginId}\" is not installed in ${scope} scope`);\n }\n savePluginRegistry(paths.registryPath, setPluginRecord(registry, pluginId, { ...record, enabled }));\n await this.reload();\n }\n\n async setConfigValue(\n pluginId: string,\n scope: PluginScope,\n key: string,\n value: MastraCodePluginConfigValue,\n ): Promise<void> {\n const paths = getPluginScopePaths(scope, this.options);\n const registry = loadPluginRegistry(paths.registryPath);\n const record = registry.plugins[pluginId];\n if (!record) {\n throw new Error(`Plugin \"${pluginId}\" is not installed in ${scope} scope`);\n }\n const config = { ...(record.config ?? {}) };\n if (value === undefined || value === '') {\n delete config[key];\n } else {\n config[key] = value;\n }\n const nextRecord = { ...record, config: Object.keys(config).length > 0 ? config : undefined };\n savePluginRegistry(paths.registryPath, setPluginRecord(registry, pluginId, nextRecord));\n await this.reload();\n }\n\n async uninstall(pluginId: string, scope: PluginScope): Promise<void> {\n const paths = getPluginScopePaths(scope, this.options);\n const registry = loadPluginRegistry(paths.registryPath);\n const record = registry.plugins[pluginId];\n if (!record) {\n throw new Error(`Plugin \"${pluginId}\" is not installed in ${scope} scope`);\n }\n\n savePluginRegistry(paths.registryPath, removePluginRecord(registry, pluginId));\n if (record.source === 'github') {\n const checkoutPath = path.resolve(\n path.isAbsolute(record.path) ? record.path : path.join(paths.root, record.path),\n );\n const githubSourcesPath = path.resolve(paths.sourcesPath, 'github');\n if (isInsideDirectory(checkoutPath, githubSourcesPath)) {\n fs.rmSync(checkoutPath, { recursive: true, force: true });\n }\n this.githubCheckoutHeads.delete(checkoutPath);\n }\n await this.reload();\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Agent } from '@mastra/core/agent';
|
|
2
|
+
import type { Mastra } from '@mastra/core/mastra';
|
|
3
|
+
import type { InputProcessorOrWorkflow, OutputProcessorOrWorkflow } from '@mastra/core/processors';
|
|
4
|
+
import type { SignalProvider } from '@mastra/core/signals';
|
|
5
|
+
import type { PluginContribution } from './types.js';
|
|
6
|
+
export type PluginSignalLaneOptions = {
|
|
7
|
+
/**
|
|
8
|
+
* Ids of providers Mastra Code wires itself (through the Agent constructor).
|
|
9
|
+
* The lane refuses to start a provider that collides with one of them:
|
|
10
|
+
* two live instances of the same provider silently clobber each other's
|
|
11
|
+
* polling, and the built-ins are invisible to the lane's own registry.
|
|
12
|
+
*/
|
|
13
|
+
reservedProviderIds?: string[];
|
|
14
|
+
onError?: (message: string, error: unknown) => void;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Owns the lifecycle of signal providers contributed by plugins.
|
|
18
|
+
*
|
|
19
|
+
* Providers are long-lived; processors are per-request. The Agent constructor
|
|
20
|
+
* conflates the two — it harvests a provider's processors into a closure that
|
|
21
|
+
* can never be undone — so plugin providers are deliberately kept out of the
|
|
22
|
+
* `signals` array and driven from here instead, through the same public methods
|
|
23
|
+
* the constructor uses. That is what makes a provider removable when its plugin
|
|
24
|
+
* is disabled, updated or uninstalled.
|
|
25
|
+
*/
|
|
26
|
+
export declare class PluginSignalLane {
|
|
27
|
+
#private;
|
|
28
|
+
constructor(options?: PluginSignalLaneOptions);
|
|
29
|
+
getInputProcessors(): readonly InputProcessorOrWorkflow[];
|
|
30
|
+
getOutputProcessors(): readonly OutputProcessorOrWorkflow[];
|
|
31
|
+
/**
|
|
32
|
+
* Reconciles the live providers against a freshly loaded plugin list.
|
|
33
|
+
*
|
|
34
|
+
* A plugin whose stamp is unchanged keeps the provider instance it already
|
|
35
|
+
* has, and the freshly resolved one is dropped without ever being registered,
|
|
36
|
+
* connected or polled — reload re-runs every plugin's resolver, so unchanged
|
|
37
|
+
* plugins hand over new instances on every call.
|
|
38
|
+
*
|
|
39
|
+
* Providers of plugins that went inactive, failed to load or were uninstalled
|
|
40
|
+
* are absent from the contributions and get stopped here.
|
|
41
|
+
*/
|
|
42
|
+
sync(contributions: PluginContribution<SignalProvider<string>>[]): void;
|
|
43
|
+
/**
|
|
44
|
+
* Called once Mastra exists. Providers resolved before then are registered and
|
|
45
|
+
* started here — without a Mastra instance a provider has no storage, and
|
|
46
|
+
* nothing else will ever hand it one: the Agent propagates Mastra only to the
|
|
47
|
+
* providers in its own `signals` array, which these deliberately are not in.
|
|
48
|
+
*/
|
|
49
|
+
setMastra(mastra: Mastra, agent: Agent): void;
|
|
50
|
+
/**
|
|
51
|
+
* Retires every live provider and empties both processor lanes. The inverse of
|
|
52
|
+
* `sync()`, for a caller that is done with this lane — an embedder sharing one
|
|
53
|
+
* `PluginManager` across controllers would otherwise leave a controller's
|
|
54
|
+
* providers polling after it is gone.
|
|
55
|
+
*/
|
|
56
|
+
stopAll(): void;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=signal-lane.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal-lane.d.ts","sourceRoot":"","sources":["../../src/plugins/signal-lane.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACnG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AASrD,MAAM,MAAM,uBAAuB,GAAG;IACpC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACrD,CAAC;AAEF;;;;;;;;;GASG;AACH,qBAAa,gBAAgB;;gBAYf,OAAO,GAAE,uBAA4B;IASjD,kBAAkB,IAAI,SAAS,wBAAwB,EAAE;IAIzD,mBAAmB,IAAI,SAAS,yBAAyB,EAAE;IAI3D;;;;;;;;;;OAUG;IACH,IAAI,CAAC,aAAa,EAAE,kBAAkB,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,IAAI;IA+BvE;;;;;OAKG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAO7C;;;;;OAKG;IACH,OAAO,IAAI,IAAI;CAyGhB"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
//#region src/plugins/signal-lane.ts
|
|
2
|
+
/**
|
|
3
|
+
* Owns the lifecycle of signal providers contributed by plugins.
|
|
4
|
+
*
|
|
5
|
+
* Providers are long-lived; processors are per-request. The Agent constructor
|
|
6
|
+
* conflates the two — it harvests a provider's processors into a closure that
|
|
7
|
+
* can never be undone — so plugin providers are deliberately kept out of the
|
|
8
|
+
* `signals` array and driven from here instead, through the same public methods
|
|
9
|
+
* the constructor uses. That is what makes a provider removable when its plugin
|
|
10
|
+
* is disabled, updated or uninstalled.
|
|
11
|
+
*/
|
|
12
|
+
var PluginSignalLane = class {
|
|
13
|
+
#live = /* @__PURE__ */ new Map();
|
|
14
|
+
#reservedProviderIds;
|
|
15
|
+
#onError;
|
|
16
|
+
#agent;
|
|
17
|
+
#mastra;
|
|
18
|
+
#inputProcessors = [];
|
|
19
|
+
#outputProcessors = [];
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
this.#reservedProviderIds = new Set(options.reservedProviderIds ?? []);
|
|
22
|
+
this.#onError = options.onError ?? ((message, error) => {
|
|
23
|
+
console.warn(message, error);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
getInputProcessors() {
|
|
27
|
+
return this.#inputProcessors;
|
|
28
|
+
}
|
|
29
|
+
getOutputProcessors() {
|
|
30
|
+
return this.#outputProcessors;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Reconciles the live providers against a freshly loaded plugin list.
|
|
34
|
+
*
|
|
35
|
+
* A plugin whose stamp is unchanged keeps the provider instance it already
|
|
36
|
+
* has, and the freshly resolved one is dropped without ever being registered,
|
|
37
|
+
* connected or polled — reload re-runs every plugin's resolver, so unchanged
|
|
38
|
+
* plugins hand over new instances on every call.
|
|
39
|
+
*
|
|
40
|
+
* Providers of plugins that went inactive, failed to load or were uninstalled
|
|
41
|
+
* are absent from the contributions and get stopped here.
|
|
42
|
+
*/
|
|
43
|
+
sync(contributions) {
|
|
44
|
+
const seen = /* @__PURE__ */ new Set();
|
|
45
|
+
for (const { pluginId, versionStamp, value: provider } of contributions) {
|
|
46
|
+
const key = `${pluginId}::${provider.id}`;
|
|
47
|
+
seen.add(key);
|
|
48
|
+
const live = this.#live.get(key);
|
|
49
|
+
if (live && live.versionStamp === versionStamp) continue;
|
|
50
|
+
if (live) this.#retire(key, live);
|
|
51
|
+
if (this.#isProviderIdTaken(provider.id)) {
|
|
52
|
+
this.#onError(`Plugin "${pluginId}" signal provider "${provider.id}" is already running; refusing to start a second instance.`, void 0);
|
|
53
|
+
seen.delete(key);
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
this.#live.set(key, {
|
|
57
|
+
pluginId,
|
|
58
|
+
provider,
|
|
59
|
+
versionStamp,
|
|
60
|
+
started: false
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
for (const [key, live] of this.#live) if (!seen.has(key)) this.#retire(key, live);
|
|
64
|
+
this.#startPending();
|
|
65
|
+
this.#rebuildProcessors();
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Called once Mastra exists. Providers resolved before then are registered and
|
|
69
|
+
* started here — without a Mastra instance a provider has no storage, and
|
|
70
|
+
* nothing else will ever hand it one: the Agent propagates Mastra only to the
|
|
71
|
+
* providers in its own `signals` array, which these deliberately are not in.
|
|
72
|
+
*/
|
|
73
|
+
setMastra(mastra, agent) {
|
|
74
|
+
this.#mastra = mastra;
|
|
75
|
+
this.#agent = agent;
|
|
76
|
+
this.#startPending();
|
|
77
|
+
this.#rebuildProcessors();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Retires every live provider and empties both processor lanes. The inverse of
|
|
81
|
+
* `sync()`, for a caller that is done with this lane — an embedder sharing one
|
|
82
|
+
* `PluginManager` across controllers would otherwise leave a controller's
|
|
83
|
+
* providers polling after it is gone.
|
|
84
|
+
*/
|
|
85
|
+
stopAll() {
|
|
86
|
+
for (const [key, live] of this.#live) this.#retire(key, live);
|
|
87
|
+
this.#rebuildProcessors();
|
|
88
|
+
}
|
|
89
|
+
#startPending() {
|
|
90
|
+
const mastra = this.#mastra;
|
|
91
|
+
const agent = this.#agent;
|
|
92
|
+
if (!mastra || !agent) return;
|
|
93
|
+
for (const [key, live] of this.#live) {
|
|
94
|
+
if (live.started) continue;
|
|
95
|
+
try {
|
|
96
|
+
live.provider.__registerMastra(mastra);
|
|
97
|
+
live.provider.connect(agent);
|
|
98
|
+
live.provider.startPolling();
|
|
99
|
+
live.started = true;
|
|
100
|
+
this.#runStart(key, live);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
this.#failProvider(key, live, error);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async #runStart(key, live) {
|
|
107
|
+
try {
|
|
108
|
+
await live.provider.start?.();
|
|
109
|
+
if (this.#live.get(key) !== live) this.#stopProvider(live);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
if (this.#live.get(key) !== live) {
|
|
112
|
+
this.#stopProvider(live);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
this.#failProvider(key, live, error);
|
|
116
|
+
this.#rebuildProcessors();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Isolated: one failing provider does not take down its plugin's tools,
|
|
121
|
+
* commands, skills or sibling providers. A plugin author who wants a provider
|
|
122
|
+
* treated as required throws from the `signalProviders` resolver instead,
|
|
123
|
+
* which fails the whole plugin record.
|
|
124
|
+
*/
|
|
125
|
+
#failProvider(key, live, error) {
|
|
126
|
+
this.#onError(`Plugin "${live.pluginId}" signal provider "${live.provider.id}" failed to start:`, error);
|
|
127
|
+
this.#retire(key, live);
|
|
128
|
+
}
|
|
129
|
+
#retire(key, live) {
|
|
130
|
+
this.#stopProvider(live);
|
|
131
|
+
this.#live.delete(key);
|
|
132
|
+
}
|
|
133
|
+
#stopProvider(live) {
|
|
134
|
+
try {
|
|
135
|
+
live.provider.stop();
|
|
136
|
+
} catch (error) {
|
|
137
|
+
this.#onError(`Plugin "${live.pluginId}" signal provider "${live.provider.id}" failed to stop:`, error);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
#isProviderIdTaken(providerId) {
|
|
141
|
+
if (this.#reservedProviderIds.has(providerId)) return true;
|
|
142
|
+
for (const live of this.#live.values()) if (live.provider.id === providerId) return true;
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
#rebuildProcessors() {
|
|
146
|
+
const input = [];
|
|
147
|
+
const output = [];
|
|
148
|
+
for (const live of this.#live.values()) {
|
|
149
|
+
if (!live.started) continue;
|
|
150
|
+
try {
|
|
151
|
+
const providerInput = live.provider.getInputProcessors?.() ?? [];
|
|
152
|
+
const providerOutput = live.provider.getOutputProcessors?.() ?? [];
|
|
153
|
+
input.push(...providerInput);
|
|
154
|
+
output.push(...providerOutput);
|
|
155
|
+
} catch (error) {
|
|
156
|
+
this.#onError(`Plugin "${live.pluginId}" signal provider "${live.provider.id}" failed to provide processors:`, error);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
this.#inputProcessors = input;
|
|
160
|
+
this.#outputProcessors = output;
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
//#endregion
|
|
164
|
+
export { PluginSignalLane };
|
|
165
|
+
|
|
166
|
+
//# sourceMappingURL=signal-lane.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal-lane.js","names":["#live","#reservedProviderIds","#onError","#inputProcessors","#outputProcessors","#retire","#isProviderIdTaken","#startPending","#rebuildProcessors","#mastra","#agent","#runStart","#failProvider","#stopProvider"],"sources":["../../src/plugins/signal-lane.ts"],"sourcesContent":["import type { Agent } from '@mastra/core/agent';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { InputProcessorOrWorkflow, OutputProcessorOrWorkflow } from '@mastra/core/processors';\nimport type { SignalProvider } from '@mastra/core/signals';\n\nimport type { PluginContribution } from './types.js';\n\ntype LiveProvider = {\n pluginId: string;\n provider: SignalProvider<string>;\n versionStamp: string;\n started: boolean;\n};\n\nexport type PluginSignalLaneOptions = {\n /**\n * Ids of providers Mastra Code wires itself (through the Agent constructor).\n * The lane refuses to start a provider that collides with one of them:\n * two live instances of the same provider silently clobber each other's\n * polling, and the built-ins are invisible to the lane's own registry.\n */\n reservedProviderIds?: string[];\n onError?: (message: string, error: unknown) => void;\n};\n\n/**\n * Owns the lifecycle of signal providers contributed by plugins.\n *\n * Providers are long-lived; processors are per-request. The Agent constructor\n * conflates the two — it harvests a provider's processors into a closure that\n * can never be undone — so plugin providers are deliberately kept out of the\n * `signals` array and driven from here instead, through the same public methods\n * the constructor uses. That is what makes a provider removable when its plugin\n * is disabled, updated or uninstalled.\n */\nexport class PluginSignalLane {\n readonly #live = new Map<string, LiveProvider>();\n readonly #reservedProviderIds: Set<string>;\n readonly #onError: (message: string, error: unknown) => void;\n #agent: Agent | undefined;\n #mastra: Mastra | undefined;\n // Replaced wholesale, never mutated: a request that already resolved its\n // processors keeps the array it read, so a reload mid-request cannot change\n // the pipeline underneath it.\n #inputProcessors: InputProcessorOrWorkflow[] = [];\n #outputProcessors: OutputProcessorOrWorkflow[] = [];\n\n constructor(options: PluginSignalLaneOptions = {}) {\n this.#reservedProviderIds = new Set(options.reservedProviderIds ?? []);\n this.#onError =\n options.onError ??\n ((message, error) => {\n console.warn(message, error);\n });\n }\n\n getInputProcessors(): readonly InputProcessorOrWorkflow[] {\n return this.#inputProcessors;\n }\n\n getOutputProcessors(): readonly OutputProcessorOrWorkflow[] {\n return this.#outputProcessors;\n }\n\n /**\n * Reconciles the live providers against a freshly loaded plugin list.\n *\n * A plugin whose stamp is unchanged keeps the provider instance it already\n * has, and the freshly resolved one is dropped without ever being registered,\n * connected or polled — reload re-runs every plugin's resolver, so unchanged\n * plugins hand over new instances on every call.\n *\n * Providers of plugins that went inactive, failed to load or were uninstalled\n * are absent from the contributions and get stopped here.\n */\n sync(contributions: PluginContribution<SignalProvider<string>>[]): void {\n const seen = new Set<string>();\n\n for (const { pluginId, versionStamp, value: provider } of contributions) {\n const key = `${pluginId}::${provider.id}`;\n seen.add(key);\n\n const live = this.#live.get(key);\n if (live && live.versionStamp === versionStamp) continue;\n if (live) this.#retire(key, live);\n\n if (this.#isProviderIdTaken(provider.id)) {\n this.#onError(\n `Plugin \"${pluginId}\" signal provider \"${provider.id}\" is already running; refusing to start a second instance.`,\n undefined,\n );\n seen.delete(key);\n continue;\n }\n\n this.#live.set(key, { pluginId, provider, versionStamp, started: false });\n }\n\n for (const [key, live] of this.#live) {\n if (!seen.has(key)) this.#retire(key, live);\n }\n\n this.#startPending();\n this.#rebuildProcessors();\n }\n\n /**\n * Called once Mastra exists. Providers resolved before then are registered and\n * started here — without a Mastra instance a provider has no storage, and\n * nothing else will ever hand it one: the Agent propagates Mastra only to the\n * providers in its own `signals` array, which these deliberately are not in.\n */\n setMastra(mastra: Mastra, agent: Agent): void {\n this.#mastra = mastra;\n this.#agent = agent;\n this.#startPending();\n this.#rebuildProcessors();\n }\n\n /**\n * Retires every live provider and empties both processor lanes. The inverse of\n * `sync()`, for a caller that is done with this lane — an embedder sharing one\n * `PluginManager` across controllers would otherwise leave a controller's\n * providers polling after it is gone.\n */\n stopAll(): void {\n for (const [key, live] of this.#live) this.#retire(key, live);\n this.#rebuildProcessors();\n }\n\n #startPending(): void {\n const mastra = this.#mastra;\n const agent = this.#agent;\n if (!mastra || !agent) return;\n\n for (const [key, live] of this.#live) {\n if (live.started) continue;\n try {\n live.provider.__registerMastra(mastra);\n live.provider.connect(agent);\n live.provider.startPolling();\n live.started = true;\n // `start()` is the provider's own warm-up and may do network work, so it\n // is not awaited — this runs on the boot path and on every plugin\n // reload, and a slow provider must not hold either up. The Agent\n // constructor treats it the same way (agent.ts: `void provider.start?.()`).\n void this.#runStart(key, live);\n } catch (error) {\n this.#failProvider(key, live, error);\n }\n }\n }\n\n async #runStart(key: string, live: LiveProvider): Promise<void> {\n try {\n await live.provider.start?.();\n // Retired or replaced while warming up: whatever `start()` just armed was\n // armed after this provider was stopped, so it is stopped again. Without\n // this a provider replaced mid-warm-up keeps working against the thread\n // its successor is now watching.\n if (this.#live.get(key) !== live) this.#stopProvider(live);\n } catch (error) {\n if (this.#live.get(key) !== live) {\n this.#stopProvider(live);\n return;\n }\n this.#failProvider(key, live, error);\n this.#rebuildProcessors();\n }\n }\n\n /**\n * Isolated: one failing provider does not take down its plugin's tools,\n * commands, skills or sibling providers. A plugin author who wants a provider\n * treated as required throws from the `signalProviders` resolver instead,\n * which fails the whole plugin record.\n */\n #failProvider(key: string, live: LiveProvider, error: unknown): void {\n this.#onError(`Plugin \"${live.pluginId}\" signal provider \"${live.provider.id}\" failed to start:`, error);\n this.#retire(key, live);\n }\n\n #retire(key: string, live: LiveProvider): void {\n this.#stopProvider(live);\n this.#live.delete(key);\n }\n\n #stopProvider(live: LiveProvider): void {\n try {\n live.provider.stop();\n } catch (error) {\n this.#onError(`Plugin \"${live.pluginId}\" signal provider \"${live.provider.id}\" failed to stop:`, error);\n }\n }\n\n #isProviderIdTaken(providerId: string): boolean {\n if (this.#reservedProviderIds.has(providerId)) return true;\n for (const live of this.#live.values()) {\n if (live.provider.id === providerId) return true;\n }\n return false;\n }\n\n #rebuildProcessors(): void {\n const input: InputProcessorOrWorkflow[] = [];\n const output: OutputProcessorOrWorkflow[] = [];\n for (const live of this.#live.values()) {\n // Only started providers contribute: one that has not been handed Mastra\n // yet has no storage, so running its processors would fail on the first\n // request rather than wait for the lifecycle to complete.\n if (!live.started) continue;\n // Guarded like every other provider call: a throwing getter drops that\n // provider's processors from this rebuild instead of unwinding the whole\n // lane mid-sync. Both getters are read before either lane is touched so a\n // provider never contributes input processors without its output ones.\n try {\n const providerInput = live.provider.getInputProcessors?.() ?? [];\n const providerOutput = live.provider.getOutputProcessors?.() ?? [];\n input.push(...providerInput);\n output.push(...providerOutput);\n } catch (error) {\n this.#onError(\n `Plugin \"${live.pluginId}\" signal provider \"${live.provider.id}\" failed to provide processors:`,\n error,\n );\n }\n }\n this.#inputProcessors = input;\n this.#outputProcessors = output;\n }\n}\n"],"mappings":"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"}
|
package/dist/plugins/types.d.ts
CHANGED
|
@@ -1,4 +1,27 @@
|
|
|
1
|
+
import type { InputProcessor, OutputProcessor } from '@mastra/core/processors';
|
|
2
|
+
import type { SignalProvider } from '@mastra/core/signals';
|
|
1
3
|
import type { MastraCodePluginConfigSchema, MastraCodePluginConfigValue, MastraCodePluginTools, MastraCodeToolRenderConfig } from '../plugin.js';
|
|
4
|
+
/** Processors a plugin contributed, normalized into the lane they belong to. */
|
|
5
|
+
export type LoadedPluginProcessors = {
|
|
6
|
+
input: InputProcessor[];
|
|
7
|
+
output: OutputProcessor[];
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* A single contribution, carrying the id of the plugin that owns it. Ownership
|
|
11
|
+
* has to survive collection: the signal lane keys live providers by
|
|
12
|
+
* `(pluginId, providerId)`, and a processor's state id is derived from the
|
|
13
|
+
* plugin id so it stays stable when the plugin is reloaded.
|
|
14
|
+
*/
|
|
15
|
+
export type PluginContribution<TValue> = {
|
|
16
|
+
pluginId: string;
|
|
17
|
+
/** The owning plugin's {@link LoadedPlugin.versionStamp} at collection time. */
|
|
18
|
+
versionStamp: string;
|
|
19
|
+
value: TValue;
|
|
20
|
+
};
|
|
21
|
+
export type PluginProcessorEntries = {
|
|
22
|
+
input: PluginContribution<InputProcessor>[];
|
|
23
|
+
output: PluginContribution<OutputProcessor>[];
|
|
24
|
+
};
|
|
2
25
|
export type PluginScope = 'global' | 'project';
|
|
3
26
|
export type PluginSource = 'local' | 'github';
|
|
4
27
|
export type PluginStatus = 'active' | 'inactive' | 'blocked' | 'load failed' | 'conflicted';
|
|
@@ -30,11 +53,24 @@ export type LoadedPlugin = ScopedInstalledPluginRecord & {
|
|
|
30
53
|
tools: MastraCodePluginTools;
|
|
31
54
|
renderConfigs?: Record<string, MastraCodeToolRenderConfig>;
|
|
32
55
|
toolNames: string[];
|
|
56
|
+
processors?: LoadedPluginProcessors;
|
|
57
|
+
signalProviders?: SignalProvider<string>[];
|
|
33
58
|
skillPaths?: string[];
|
|
34
59
|
commandPaths?: string[];
|
|
35
60
|
configSchema?: MastraCodePluginConfigSchema;
|
|
36
61
|
configValues?: Record<string, MastraCodePluginConfigValue>;
|
|
37
62
|
conflicts?: string[];
|
|
63
|
+
/**
|
|
64
|
+
* Changes when this plugin's contributions should be rebuilt: source content
|
|
65
|
+
* (git HEAD for GitHub checkouts, entry file version for local plugins) plus
|
|
66
|
+
* the registry record's config values and enabled flag. Reload fires on
|
|
67
|
+
* non-content events too — a config edit hands the plugin different values
|
|
68
|
+
* while every file is untouched — so both halves matter.
|
|
69
|
+
*
|
|
70
|
+
* Consumers that own long-lived instances (the signal-provider lane) compare
|
|
71
|
+
* this to decide between keeping what they have and cycling it.
|
|
72
|
+
*/
|
|
73
|
+
versionStamp?: string;
|
|
38
74
|
};
|
|
39
75
|
export type PluginScopePaths = {
|
|
40
76
|
scope: PluginScope;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/plugins/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,4BAA4B,EAC5B,2BAA2B,EAC3B,qBAAqB,EACrB,0BAA0B,EAC3B,MAAM,cAAc,CAAC;AAEtB,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;AAC/C,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,CAAC;AAC9C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,YAAY,CAAC;AAE5F,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAC/C,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG,qBAAqB,GAAG;IAChE,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,2BAA2B,GAAG;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,qBAAqB,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,0BAA0B,CAAC,CAAC;IAC3D,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,4BAA4B,CAAC;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;IAC3D,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/plugins/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ import type { MastraModelConfig } from '@mastra/core/llm';
|
|
|
8
8
|
import type { LanguageModelMiddleware } from 'ai';
|
|
9
9
|
import { AuthStorage } from '../auth/storage.js';
|
|
10
10
|
import type { CredentialStore } from '../auth/types.js';
|
|
11
|
+
import type { ThinkingLevel } from './openai-codex.js';
|
|
11
12
|
/**
|
|
12
13
|
* Get or create the shared AuthStorage instance
|
|
13
14
|
*/
|
|
@@ -33,6 +34,17 @@ export declare const claudeCodeMiddleware: LanguageModelMiddleware;
|
|
|
33
34
|
* - Conversation history up to the last message
|
|
34
35
|
*/
|
|
35
36
|
export declare const promptCacheMiddleware: LanguageModelMiddleware;
|
|
37
|
+
/**
|
|
38
|
+
* Middleware that maps the session thinking level onto Anthropic extended
|
|
39
|
+
* thinking. Returns `undefined` (no middleware) when the level is `off` or the
|
|
40
|
+
* model doesn't support thinking, preserving the previous request shape.
|
|
41
|
+
*
|
|
42
|
+
* - Adaptive-era models (Sonnet 4.6+/Opus 4.6+): `thinking: adaptive` plus
|
|
43
|
+
* `output_config.effort` mapped 1:1 from the level (including `max`).
|
|
44
|
+
* - Budget-era models (Claude 3.7 – Opus 4.5): `thinking: enabled` with a
|
|
45
|
+
* `budget_tokens` value derived from the level.
|
|
46
|
+
*/
|
|
47
|
+
export declare function createAnthropicThinkingMiddleware(modelId: string, thinkingLevel?: ThinkingLevel): LanguageModelMiddleware | undefined;
|
|
36
48
|
/**
|
|
37
49
|
* Build a fetch function that handles Anthropic OAuth.
|
|
38
50
|
* Preserves non-auth headers from init (critical for gateway auth header to survive
|
|
@@ -48,5 +60,6 @@ export declare function buildAnthropicOAuthFetch(opts?: {
|
|
|
48
60
|
export declare function opencodeClaudeMaxProvider(modelId?: string, options?: {
|
|
49
61
|
headers?: Record<string, string>;
|
|
50
62
|
authStorage?: CredentialStore;
|
|
63
|
+
thinkingLevel?: ThinkingLevel;
|
|
51
64
|
}): MastraModelConfig;
|
|
52
65
|
//# sourceMappingURL=claude-max.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-max.d.ts","sourceRoot":"","sources":["../../src/providers/claude-max.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,IAAI,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"claude-max.d.ts","sourceRoot":"","sources":["../../src/providers/claude-max.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,IAAI,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAoBvD;;GAEG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAK5C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI,CAErE;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,uBAkBlC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,qBAAqB,EAAE,uBA2DnC,CAAC;AA+CF;;;;;;;;;GASG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,aAAa,GAC5B,uBAAuB,GAAG,SAAS,CAiCrC;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,eAAe,CAAA;CAAO,GAAG,OAAO,KAAK,CAmDnG;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,MAAmC,EAC5C,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,WAAW,CAAC,EAAE,eAAe,CAAC;IAAC,aAAa,CAAC,EAAE,aAAa,CAAA;CAAE,GAC3G,iBAAiB,CA4BnB"}
|
|
@@ -111,6 +111,80 @@ const promptCacheMiddleware = {
|
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
113
|
};
|
|
114
|
+
const ANTHROPIC_EFFORT = {
|
|
115
|
+
low: "low",
|
|
116
|
+
medium: "medium",
|
|
117
|
+
high: "high",
|
|
118
|
+
xhigh: "xhigh",
|
|
119
|
+
max: "max"
|
|
120
|
+
};
|
|
121
|
+
const ANTHROPIC_XHIGH_EFFORT_RE = /claude-(?:opus-4-[78]|opus-5|sonnet-5|fable-5)/;
|
|
122
|
+
function getAnthropicEffort(modelId, level) {
|
|
123
|
+
if (level === "xhigh" && !ANTHROPIC_XHIGH_EFFORT_RE.test(modelId)) return "high";
|
|
124
|
+
return ANTHROPIC_EFFORT[level];
|
|
125
|
+
}
|
|
126
|
+
const ANTHROPIC_THINKING_BUDGET_TOKENS = {
|
|
127
|
+
low: 4096,
|
|
128
|
+
medium: 8192,
|
|
129
|
+
high: 16384,
|
|
130
|
+
xhigh: 24576,
|
|
131
|
+
max: 24576
|
|
132
|
+
};
|
|
133
|
+
/** Claude generations that support adaptive thinking + `output_config.effort`. */
|
|
134
|
+
const ADAPTIVE_THINKING_RE = /claude-(?:sonnet-4-6|opus-4-[678]|opus-5|sonnet-5|fable-5)/;
|
|
135
|
+
/** Older generations that support extended thinking via `budget_tokens`. */
|
|
136
|
+
const BUDGET_THINKING_RE = /claude-(?:3-7|sonnet-4|opus-4|haiku-4-5)/;
|
|
137
|
+
/** Generations with no extended-thinking support at all. */
|
|
138
|
+
const NO_THINKING_RE = /claude-(?:instant|v?2(?:[-.:]|$)|3(?:[-.]|$)|3-5)/;
|
|
139
|
+
function getAnthropicThinkingCapability(modelId) {
|
|
140
|
+
if (ADAPTIVE_THINKING_RE.test(modelId)) return "adaptive";
|
|
141
|
+
if (BUDGET_THINKING_RE.test(modelId)) return "budget";
|
|
142
|
+
if (NO_THINKING_RE.test(modelId)) return "none";
|
|
143
|
+
return "adaptive";
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Middleware that maps the session thinking level onto Anthropic extended
|
|
147
|
+
* thinking. Returns `undefined` (no middleware) when the level is `off` or the
|
|
148
|
+
* model doesn't support thinking, preserving the previous request shape.
|
|
149
|
+
*
|
|
150
|
+
* - Adaptive-era models (Sonnet 4.6+/Opus 4.6+): `thinking: adaptive` plus
|
|
151
|
+
* `output_config.effort` mapped 1:1 from the level (including `max`).
|
|
152
|
+
* - Budget-era models (Claude 3.7 – Opus 4.5): `thinking: enabled` with a
|
|
153
|
+
* `budget_tokens` value derived from the level.
|
|
154
|
+
*/
|
|
155
|
+
function createAnthropicThinkingMiddleware(modelId, thinkingLevel) {
|
|
156
|
+
if (!thinkingLevel || thinkingLevel === "off") return void 0;
|
|
157
|
+
const capability = getAnthropicThinkingCapability(modelId);
|
|
158
|
+
if (capability === "none") return void 0;
|
|
159
|
+
const level = thinkingLevel;
|
|
160
|
+
return {
|
|
161
|
+
specificationVersion: "v3",
|
|
162
|
+
transformParams: async ({ params }) => {
|
|
163
|
+
const anthropicOptions = params.providerOptions?.anthropic ?? {};
|
|
164
|
+
if (anthropicOptions.thinking !== void 0 || anthropicOptions.effort !== void 0) return params;
|
|
165
|
+
delete params.temperature;
|
|
166
|
+
delete params.topP;
|
|
167
|
+
delete params.topK;
|
|
168
|
+
params.providerOptions = {
|
|
169
|
+
...params.providerOptions,
|
|
170
|
+
anthropic: {
|
|
171
|
+
...anthropicOptions,
|
|
172
|
+
...capability === "adaptive" ? {
|
|
173
|
+
thinking: {
|
|
174
|
+
type: "adaptive",
|
|
175
|
+
display: "summarized"
|
|
176
|
+
},
|
|
177
|
+
effort: getAnthropicEffort(modelId, level)
|
|
178
|
+
} : { thinking: {
|
|
179
|
+
type: "enabled",
|
|
180
|
+
budgetTokens: ANTHROPIC_THINKING_BUDGET_TOKENS[level]
|
|
181
|
+
} }
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
return params;
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
}
|
|
114
188
|
/**
|
|
115
189
|
* Build a fetch function that handles Anthropic OAuth.
|
|
116
190
|
* Preserves non-auth headers from init (critical for gateway auth header to survive
|
|
@@ -149,12 +223,18 @@ function buildAnthropicOAuthFetch(opts = {}) {
|
|
|
149
223
|
*/
|
|
150
224
|
function opencodeClaudeMaxProvider(modelId = "claude-sonnet-4-20250514", options) {
|
|
151
225
|
const headers = options?.headers;
|
|
226
|
+
const thinkingMiddleware = createAnthropicThinkingMiddleware(modelId, options?.thinkingLevel);
|
|
227
|
+
const middleware = [
|
|
228
|
+
claudeCodeMiddleware,
|
|
229
|
+
promptCacheMiddleware,
|
|
230
|
+
...thinkingMiddleware ? [thinkingMiddleware] : []
|
|
231
|
+
];
|
|
152
232
|
if (process.env.NODE_ENV === "test" || process.env.VITEST) return wrapLanguageModel({
|
|
153
233
|
model: createAnthropic({
|
|
154
234
|
apiKey: "test-api-key",
|
|
155
235
|
headers
|
|
156
236
|
})(modelId),
|
|
157
|
-
middleware
|
|
237
|
+
middleware
|
|
158
238
|
});
|
|
159
239
|
return wrapLanguageModel({
|
|
160
240
|
model: createAnthropic({
|
|
@@ -162,10 +242,10 @@ function opencodeClaudeMaxProvider(modelId = "claude-sonnet-4-20250514", options
|
|
|
162
242
|
headers,
|
|
163
243
|
fetch: buildAnthropicOAuthFetch({ authStorage: options?.authStorage })
|
|
164
244
|
})(modelId),
|
|
165
|
-
middleware
|
|
245
|
+
middleware
|
|
166
246
|
});
|
|
167
247
|
}
|
|
168
248
|
//#endregion
|
|
169
|
-
export { buildAnthropicOAuthFetch, claudeCodeMiddleware, getAuthStorage, opencodeClaudeMaxProvider, promptCacheMiddleware, setAuthStorage };
|
|
249
|
+
export { buildAnthropicOAuthFetch, claudeCodeMiddleware, createAnthropicThinkingMiddleware, getAuthStorage, opencodeClaudeMaxProvider, promptCacheMiddleware, setAuthStorage };
|
|
170
250
|
|
|
171
251
|
//# sourceMappingURL=claude-max.js.map
|