OneBot: Leantime 改造版源码(BOM/Univer 表格/AI 接管/品牌替换等)
This commit is contained in:
79
app/Mcp/Servers/OneBotServer.php
Normal file
79
app/Mcp/Servers/OneBotServer.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Leantime\Mcp\Servers;
|
||||
|
||||
use Laravel\Mcp\Server as McpServer;
|
||||
use Laravel\Mcp\Server\Tool;
|
||||
|
||||
/**
|
||||
* OneBot 的 MCP server:暴露所有 Domain 下 Tools 目录里定义的 AI 工具。
|
||||
*
|
||||
* 采用 boot() 动态发现(扫描 app/Domain 各域的 Tools 目录),而非静态 tools 数组,
|
||||
* 这样后续新增任何域的 Tool 类都会自动注册,无需改这里。
|
||||
*/
|
||||
class OneBotServer extends McpServer
|
||||
{
|
||||
public string $serverName = 'OneBot';
|
||||
|
||||
public string $serverVersion = '1.0.0';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->instructions = implode("\n", [
|
||||
'你是 OneBot 项目管理系统的 AI 助手,可通过工具直接操作系统完成用户指令。',
|
||||
'',
|
||||
'【身份】你有系统操作能力,但只是辅助;涉及删除、批量修改、覆盖导入等高风险写操作前,必须先列出将影响的数据并征得用户明确确认。',
|
||||
'',
|
||||
'【业务规则】',
|
||||
'- BOM / 工艺文件 / 工具清单是「全局主数据」(跨项目共享),修改会影响所有引用它的项目。',
|
||||
'- 项目对主数据是「单向引用」:项目级追加的列/值不影响全局主数据。',
|
||||
'- 删除、批量修改、覆盖导入前,先列影响并确认。',
|
||||
'',
|
||||
'【边界】不臆造数据;工具返回错误时如实报告并给排查建议,不反复重试同一失败操作;回答用简体中文;金额用人民币。',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 动态发现并注册所有 Domain Tools。
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
$pattern = app()->basePath('app/Domain/*/Tools/*Tool.php');
|
||||
$files = glob($pattern) ?: [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$class = $this->classFromFile($file);
|
||||
if ($class !== null && class_exists($class) && is_subclass_of($class, Tool::class)) {
|
||||
try {
|
||||
$this->addTool($class);
|
||||
} catch (\Throwable $e) {
|
||||
// 单个工具失败不阻断整个 server 启动
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文件路径推导类名:app/Domain/Projects/Tools/GetAllProjectsTool.php
|
||||
* → Leantime\Domain\Projects\Tools\GetAllProjectsTool
|
||||
*/
|
||||
private function classFromFile(string $file): ?string
|
||||
{
|
||||
$appRoot = rtrim(app()->basePath('app'), '/\\');
|
||||
if (! str_starts_with($file, $appRoot)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$relative = substr($file, strlen($appRoot));
|
||||
$relative = ltrim(str_replace(['/', '\\'], '\\', $relative), '\\');
|
||||
$relative = preg_replace('/\.php$/', '', $relative);
|
||||
|
||||
if ($relative === '' || $relative === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return app()->getNamespace().$relative;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user