This commit is contained in:
Twilight 2024-07-24 01:35:03 +08:00
parent 98710825b8
commit 21b2254379
8 changed files with 160 additions and 105 deletions

View File

@ -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);
}
/**

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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'] ?? [];
}
}

View File

@ -35,4 +35,9 @@
],
],
'dashscope' => [
'api_key' => env('DASHSCOPE_API_KEY'),
'api_base' => env('DASHSCOPE_API_BASE', 'https://dashscope.aliyuncs.com'),
]
];

View File

@ -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');

View File

@ -1,37 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('tool_functions', function (Blueprint $table) {
$table->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');
}
};

View File

@ -1,28 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('tools', function (Blueprint $table) {
$table->string('callback_url')->after('api_key');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('tools', function (Blueprint $table) {
$table->dropColumn('callback_url');
});
}
};