diff --git a/app/Http/Controllers/Web/ToolController.php b/app/Http/Controllers/Web/ToolController.php index 14dc294..f69a4d7 100644 --- a/app/Http/Controllers/Web/ToolController.php +++ b/app/Http/Controllers/Web/ToolController.php @@ -4,11 +4,13 @@ use Apiboard\OpenAPI\OpenAPI; use App\Http\Controllers\Controller; +use App\Repositories\Tool\Tool; use cebe\openapi\exceptions\IOException; use cebe\openapi\exceptions\TypeErrorException; use cebe\openapi\exceptions\UnresolvableReferenceException; use cebe\openapi\json\InvalidJsonPointerSyntaxException; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Http; class ToolController extends Controller { @@ -20,32 +22,31 @@ public function index() // } - /** - * @throws IOException - * @throws TypeErrorException - * @throws UnresolvableReferenceException - * @throws InvalidJsonPointerSyntaxException - */ - public function getOpenAPI() - { - $url = 'http://127.0.0.1:8081/openapi.yml'; - - $file = file_get_contents($url); - - // $openAPI = new OpenAPI(); - // - // $document = $openAPI->parse($file); - // - // - // dd($document->openapi()); - } - /** * Store a newly created resource in storage. + * @throws \Exception */ public function store(Request $request) { - // + $request->validate([ + 'name' => 'string|required', + 'description' => 'string|nullable', + 'url' => 'string|required', + 'api_key' => 'string|nullable', + ]); + + $url = $request->input('url'); + + + $url = "localhost:8081/fn.php"; + + $json = Http::get($url); + + + + $tool = new Tool($json->json()); + + dd($tool); } /** diff --git a/app/LLM/Qwen.php b/app/LLM/Qwen.php index c3dc8eb..b9c58e3 100644 --- a/app/LLM/Qwen.php +++ b/app/LLM/Qwen.php @@ -2,8 +2,11 @@ namespace App\LLM; +use GuzzleHttp\Client; + class Qwen extends Base { + protected string $model = "qwen-max"; /** * Create a new class instance. */ @@ -11,4 +14,48 @@ public function __construct() { // } + + public function getResponse() + { + $client = new Client([ + 'headers' => [ + 'Content-Type' => 'application/json', + 'Accept' => 'text/event-stream', + 'Cache-Control' => 'no-cache', + 'Authorization' => 'Bearer ' . config('services.dashscope.api_key'), + ] + ]); + + $url = config('services.dashscope.api_base') . '/compatible-mode/v1/chat/completions'; + + $messages = [ + [ + 'role' => 'user', + 'content' => "你好", + ], + ]; + + $jsonBody = json_encode([ + 'model' => $this->model, + 'messages' => $messages, + 'stream' => true + ]); + + $response = $client->request('POST', $url, [ + 'body' => $jsonBody, + 'stream' => true, + ]); + + $body = $response->getBody(); +// while (!$body->eof()) { +// echo $body->read(1024); +// } + + while (!$body->eof()) { +// $body->read(1); + echo $body->read(1); + } + + + } } diff --git a/app/Repositories/Tool/Tool.php b/app/Repositories/Tool/Tool.php index 05dc276..e988273 100644 --- a/app/Repositories/Tool/Tool.php +++ b/app/Repositories/Tool/Tool.php @@ -8,42 +8,60 @@ class Tool { public string $name; - public string $url; + public string $homepage_url; + public string $callback_url; public string $description; - public string $api_key; + public array $toolFunctions; - public string $user_id; + private array $data; /** * @throws Exception */ - public function parse(array $data): void + public function __construct(array $data) + { + $this->data = $data; + $this->parse(); + } + /** + * @throws Exception + */ + private function parse(): void { // 验证数据 - if (! $this->validate($data)) { + if (! $this->validate()) { throw new Exception('Invalid data'); } - $this->name = $data['name']; - $this->url = $data['url']; - $this->description = $data['description']; - $this->api_key = $data['api_key']; - $this->user_id = $data['user_id']; + $this->name = $this->data['name']; + $this->description = $this->data['description']; + $this->homepage_url = $this->data['homepage_url']; + $this->callback_url = $this->data['callback_url']; + $this->fetchFunctions(); } - public function validate(array $data): bool + private function validate(): bool { // all fields are required - if (empty($data['name']) || - empty($data['url']) || - empty($data['description']) || - empty($data['api_key']) || - empty($data['user_id'])) { + if (empty($this->data['name']) || + empty($this->data['description']) || + empty($this->data['homepage_url']) || + empty($this->data['callback_url'])) { return false; } return true; } + + /** + * @throws Exception + */ + private function fetchFunctions(): void + { + foreach ($this->data['functions'] as $f) { + $this->toolFunctions[] = new ToolFunction($f); + } + } } diff --git a/app/Repositories/Tool/ToolFunction.php b/app/Repositories/Tool/ToolFunction.php index 476d721..57c5c53 100644 --- a/app/Repositories/Tool/ToolFunction.php +++ b/app/Repositories/Tool/ToolFunction.php @@ -2,13 +2,59 @@ namespace App\Repositories\Tool; +use Exception; + class ToolFunction { + public string $name; + public string $description; + public array $parameters; + protected array $data; + public array $required; + /** * Create a new class instance. + * @throws Exception */ - public function __construct() + public function __construct(array $data) { - // + $this->data = $data; + $this->parse(); + } + + /** + * @throws Exception + */ + private function parse(): void + { + $this->name = $this->data['name']; + $this->description = $this->data['description']; + + // 如果 parameters 不为空,则验证 + if (! empty($this->data['parameters'])) { + // 检查 type 是否为 object + if ($this->data['parameters']['type'] !== 'object') { + throw new Exception('parameters type must be object'); + } + + if (! isset($this->data['parameters']['properties'])) { + throw new Exception('parameters must have properties'); + } + + // 循环检查 properties 下的 key 的值,必须有 type 和 description + foreach ($this->data['parameters']['properties'] as $key => $value) { + if (! isset($value['type'])) { + throw new Exception('parameters properties must have type'); + } + + if (! isset($value['description'])) { + throw new Exception('parameters properties must have description'); + } + } + } + + $this->parameters = $this->data['parameters']; + + $this->required = $this->data['required'] ?? []; } } diff --git a/config/services.php b/config/services.php index 27a3617..15347b7 100644 --- a/config/services.php +++ b/config/services.php @@ -35,4 +35,9 @@ ], ], + 'dashscope' => [ + 'api_key' => env('DASHSCOPE_API_KEY'), + 'api_base' => env('DASHSCOPE_API_BASE', 'https://dashscope.aliyuncs.com'), + ] + ]; diff --git a/database/migrations/2024_07_23_093256_create_tools_table.php b/database/migrations/2024_07_23_093256_create_tools_table.php index 3c4587a..460bdf4 100644 --- a/database/migrations/2024_07_23_093256_create_tools_table.php +++ b/database/migrations/2024_07_23_093256_create_tools_table.php @@ -17,10 +17,13 @@ public function up(): void $table->string('name'); $table->string('description')->nullable(); - $table->string('url'); + $table->string('discovery_url'); $table->string('api_key')->nullable(); + // 数据 + $table->json('data')->nullable(); + // user id $table->unsignedBigInteger('user_id')->index(); $table->foreign('user_id')->references('id')->on('users'); diff --git a/database/migrations/2024_07_23_132343_create_tool_functions_table.php b/database/migrations/2024_07_23_132343_create_tool_functions_table.php deleted file mode 100644 index 27c5307..0000000 --- a/database/migrations/2024_07_23_132343_create_tool_functions_table.php +++ /dev/null @@ -1,37 +0,0 @@ -id(); - - $table->foreignId('tool_id')->constrained()->cascadeOnDelete(); - // index - $table->index(['tool_id']); - - $table->string('name')->index(); - $table->string('description'); - $table->json('parameters'); - $table->json('required'); - - $table->timestamps(); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('tool_functions'); - } -}; diff --git a/database/migrations/2024_07_23_153355_add_callback_url_to_tools_table.php b/database/migrations/2024_07_23_153355_add_callback_url_to_tools_table.php deleted file mode 100644 index 2eabdd3..0000000 --- a/database/migrations/2024_07_23_153355_add_callback_url_to_tools_table.php +++ /dev/null @@ -1,28 +0,0 @@ -string('callback_url')->after('api_key'); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::table('tools', function (Blueprint $table) { - $table->dropColumn('callback_url'); - }); - } -};