From 0097f2e7399151d49542094b8b196b71dbdc5372 Mon Sep 17 00:00:00 2001 From: Twilight Date: Tue, 23 Jul 2024 23:22:09 +0800 Subject: [PATCH] init --- .env.example | 4 + .../Controllers/Web/AssistantController.php | 49 ++ app/Http/Controllers/Web/AuthController.php | 142 +++++ app/Http/Controllers/Web/ChatController.php | 49 ++ app/Http/Controllers/Web/ToolController.php | 76 +++ app/LLM/Base.php | 8 + app/LLM/Qwen.php | 14 + app/Models/Assistant.php | 11 + app/Models/AssistantTool.php | 11 + app/Models/ChatHistory.php | 11 + app/Models/Tool.php | 11 + app/Models/ToolFunction.php | 11 + app/Tools/BaseTool.php | 22 + composer.json | 2 + composer.lock | 578 +++++++++++++++--- config/oauth.php | 7 + ...4_07_23_093251_create_assistants_table.php | 36 ++ .../2024_07_23_093256_create_tools_table.php | 39 ++ .../2024_07_23_093301_create_chats_table.php | 37 ++ ..._23_132343_create_tool_functions_table.php | 37 ++ ...23_145223_create_assistant_tools_table.php | 34 ++ ..._23_151217_create_chat_histories_table.php | 46 ++ routes/web.php | 10 +- 23 files changed, 1171 insertions(+), 74 deletions(-) create mode 100644 app/Http/Controllers/Web/AssistantController.php create mode 100644 app/Http/Controllers/Web/AuthController.php create mode 100644 app/Http/Controllers/Web/ChatController.php create mode 100644 app/Http/Controllers/Web/ToolController.php create mode 100644 app/LLM/Base.php create mode 100644 app/LLM/Qwen.php create mode 100644 app/Models/Assistant.php create mode 100644 app/Models/AssistantTool.php create mode 100644 app/Models/ChatHistory.php create mode 100644 app/Models/Tool.php create mode 100644 app/Models/ToolFunction.php create mode 100644 app/Tools/BaseTool.php create mode 100644 config/oauth.php create mode 100644 database/migrations/2024_07_23_093251_create_assistants_table.php create mode 100644 database/migrations/2024_07_23_093256_create_tools_table.php create mode 100644 database/migrations/2024_07_23_093301_create_chats_table.php create mode 100644 database/migrations/2024_07_23_132343_create_tool_functions_table.php create mode 100644 database/migrations/2024_07_23_145223_create_assistant_tools_table.php create mode 100644 database/migrations/2024_07_23_151217_create_chat_histories_table.php diff --git a/.env.example b/.env.example index 8f23061..b574c76 100644 --- a/.env.example +++ b/.env.example @@ -62,3 +62,7 @@ AWS_BUCKET= AWS_USE_PATH_STYLE_ENDPOINT=false VITE_APP_NAME="${APP_NAME}" + +OAUTH_DISCOVERY_URL=https://auth.leaflow.cn/.well-known/openid-configuration +OAUTH_CLIENT_ID= +OAUTH_CLIENT_SECRET= diff --git a/app/Http/Controllers/Web/AssistantController.php b/app/Http/Controllers/Web/AssistantController.php new file mode 100644 index 0000000..082ce5b --- /dev/null +++ b/app/Http/Controllers/Web/AssistantController.php @@ -0,0 +1,49 @@ +has($cache_key)) { + $oauth_discovery = cache()->get($cache_key); + } else { + // lock 防止重复请求 + $oauth_discovery = cache()->remember($cache_key, 3600, function () { + $client = new Client(); + $response = $client->get(config('oauth.discovery')); + + return json_decode($response->getBody(), true); + }); + } + + $this->auth_url = $oauth_discovery['authorization_endpoint']; + $this->token_url = $oauth_discovery['token_endpoint']; + $this->user_url = $oauth_discovery['userinfo_endpoint']; + $this->callback_url = route('oauth.callback'); + } + + public function redirect(Request $request) + { + $request->session()->put('state', $state = Str::random(40)); + + $query = http_build_query([ + 'client_id' => config('oauth.client_id'), + 'redirect_uri' => $this->callback_url, + 'response_type' => 'code', + 'scope' => $this->scopes, + 'state' => $state, + ]); + + return redirect()->to($this->auth_url.'?'.$query); + } + + /** + * @throws GuzzleException + */ + public function callback(Request $request) + { + $state = $request->session()->pull('state'); + + if (strlen($state) > 0 && $state !== $request->state) { + return redirect()->route('login'); + } + + // if access_denied + if ($request->error) { + return redirect()->route('home'); + } + + $http = new Client; + + try { + $authorize = $http->post($this->token_url, [ + 'form_params' => [ + 'grant_type' => 'authorization_code', + 'client_id' => config('oauth.client_id'), + 'client_secret' => config('oauth.client_secret'), + 'redirect_uri' => $this->callback_url, + 'code' => $request->code, + ], + ]); + } catch (ClientException $e) { + return redirect()->route('home'); + } + + $authorize = json_decode($authorize->getBody()); + + $oauth_user = $http->get($this->user_url, [ + 'headers' => [ + 'Accept' => 'application/json', + 'Authorization' => 'Bearer '.$authorize->access_token, + ], + ])->getBody(); + $oauth_user = json_decode($oauth_user); + + $user_sql = User::where('email', $oauth_user->email); + + $user = $user_sql->first(); + + if (is_null($user)) { + $name = $oauth_user->name; + $email = $oauth_user->email; + $email_verified_at = $oauth_user->email_verified ? now() : null; + $api_token = Str::random(50); + $user = User::create([ + 'name' => $name, + 'email' => $email, + 'email_verified_at' => $email_verified_at, + 'api_token' => $api_token, + 'password' => Hash::make(Str::random(50)), + ]); + $request->session()->put('auth.password_confirmed_at', time()); + } else { + if ($user->name != $oauth_user->name) { + User::where('email', $oauth_user->email)->update([ + 'name' => $oauth_user->name, + ]); + } + } + + Auth::loginUsingId($user->id, true); + + return redirect()->route('home'); + } +} diff --git a/app/Http/Controllers/Web/ChatController.php b/app/Http/Controllers/Web/ChatController.php new file mode 100644 index 0000000..9641c86 --- /dev/null +++ b/app/Http/Controllers/Web/ChatController.php @@ -0,0 +1,49 @@ +parse($file); +// +// +// dd($document->openapi()); + } + + /** + * Store a newly created resource in storage. + */ + public function store(Request $request) + { + // + } + + /** + * Display the specified resource. + */ + public function show(string $id) + { + // + } + + /** + * Update the specified resource in storage. + */ + public function update(Request $request, string $id) + { + // + } + + /** + * Remove the specified resource from storage. + */ + public function destroy(string $id) + { + // + } +} diff --git a/app/LLM/Base.php b/app/LLM/Base.php new file mode 100644 index 0000000..7cb6273 --- /dev/null +++ b/app/LLM/Base.php @@ -0,0 +1,8 @@ +=8.1", + "symfony/filesystem": "^6.2||^7.0", + "symfony/yaml": "^6.1||^7.0" + }, + "require-dev": { + "laravel/pint": "^1.4", + "pestphp/pest": "^1.22", + "php-mock/php-mock": "^2.5", + "spatie/invade": "^1.1", + "symfony/var-dumper": "^6.1||^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Apiboard\\OpenAPI\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "OpenAPI Specification parser for PHP 8. Supports both OAS 3.0 and 3.1.", + "support": { + "source": "https://github.com/Apiboard/php-openapi/tree/2.1.0" + }, + "time": "2024-02-21T20:55:11+00:00" + }, { "name": "brick/math", "version": "0.12.1", @@ -135,6 +178,75 @@ ], "time": "2024-02-09T16:56:22+00:00" }, + { + "name": "cebe/php-openapi", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/cebe/php-openapi.git", + "reference": "020d72b8e3a9a60bc229953e93eda25c49f46f45" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cebe/php-openapi/zipball/020d72b8e3a9a60bc229953e93eda25c49f46f45", + "reference": "020d72b8e3a9a60bc229953e93eda25c49f46f45", + "shasum": "" + }, + "require": { + "ext-json": "*", + "justinrainbow/json-schema": "^5.2", + "php": ">=7.1.0", + "symfony/yaml": "^3.4 || ^4 || ^5 || ^6" + }, + "conflict": { + "symfony/yaml": "3.4.0 - 3.4.4 || 4.0.0 - 4.4.17 || 5.0.0 - 5.1.9 || 5.2.0" + }, + "require-dev": { + "apis-guru/openapi-directory": "1.0.0", + "cebe/indent": "*", + "mermade/openapi3-examples": "1.0.0", + "nexmo/api-specification": "1.0.0", + "oai/openapi-specification": "3.0.3", + "phpstan/phpstan": "^0.12.0", + "phpunit/phpunit": "^6.5 || ^7.5 || ^8.5 || ^9.4" + }, + "bin": [ + "bin/php-openapi" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "cebe\\openapi\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Carsten Brandt", + "email": "mail@cebe.cc", + "homepage": "https://cebe.cc/", + "role": "Creator" + } + ], + "description": "Read and write OpenAPI yaml/json files and make the content accessable in PHP objects.", + "homepage": "https://github.com/cebe/php-openapi#readme", + "keywords": [ + "openapi" + ], + "support": { + "issues": "https://github.com/cebe/php-openapi/issues", + "source": "https://github.com/cebe/php-openapi" + }, + "time": "2022-04-20T14:46:44+00:00" + }, { "name": "dflydev/dot-access-data", "version": "v3.0.3", @@ -1050,6 +1162,71 @@ ], "time": "2023-12-03T19:50:20+00:00" }, + { + "name": "justinrainbow/json-schema", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/jsonrainbow/json-schema.git", + "reference": "feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8", + "reference": "feb2ca6dd1cebdaf1ed60a4c8de2e53ce11c4fd8", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.35" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "support": { + "issues": "https://github.com/jsonrainbow/json-schema/issues", + "source": "https://github.com/jsonrainbow/json-schema/tree/5.3.0" + }, + "time": "2024-07-06T21:00:26+00:00" + }, { "name": "laravel/framework", "version": "v11.16.0", @@ -2317,6 +2494,196 @@ ], "time": "2024-03-06T16:17:14+00:00" }, + { + "name": "opis/json-schema", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/opis/json-schema.git", + "reference": "c48df6d7089a45f01e1c82432348f2d5976f9bfb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/json-schema/zipball/c48df6d7089a45f01e1c82432348f2d5976f9bfb", + "reference": "c48df6d7089a45f01e1c82432348f2d5976f9bfb", + "shasum": "" + }, + "require": { + "ext-json": "*", + "opis/string": "^2.0", + "opis/uri": "^1.0", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "ext-bcmath": "*", + "ext-intl": "*", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\JsonSchema\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + }, + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + } + ], + "description": "Json Schema Validator for PHP", + "homepage": "https://opis.io/json-schema", + "keywords": [ + "json", + "json-schema", + "schema", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/opis/json-schema/issues", + "source": "https://github.com/opis/json-schema/tree/2.3.0" + }, + "time": "2022-01-08T20:38:03+00:00" + }, + { + "name": "opis/string", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/opis/string.git", + "reference": "9ebf1a1f873f502f6859d11210b25a4bf5d141e7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/string/zipball/9ebf1a1f873f502f6859d11210b25a4bf5d141e7", + "reference": "9ebf1a1f873f502f6859d11210b25a4bf5d141e7", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "ext-json": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\String\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + }, + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + } + ], + "description": "Multibyte strings as objects", + "homepage": "https://opis.io/string", + "keywords": [ + "multi-byte", + "opis", + "string", + "string manipulation", + "utf-8" + ], + "support": { + "issues": "https://github.com/opis/string/issues", + "source": "https://github.com/opis/string/tree/2.0.1" + }, + "time": "2022-01-14T15:42:23+00:00" + }, + { + "name": "opis/uri", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/opis/uri.git", + "reference": "0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/uri/zipball/0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a", + "reference": "0f3ca49ab1a5e4a6681c286e0b2cc081b93a7d5a", + "shasum": "" + }, + "require": { + "opis/string": "^2.0", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\Uri\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + }, + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + } + ], + "description": "Build, parse and validate URIs and URI-templates", + "homepage": "https://opis.io", + "keywords": [ + "URI Template", + "parse url", + "punycode", + "uri", + "uri components", + "url", + "validate uri" + ], + "support": { + "issues": "https://github.com/opis/uri/issues", + "source": "https://github.com/opis/uri/tree/1.1.0" + }, + "time": "2021-05-22T15:57:08+00:00" + }, { "name": "phpoption/phpoption", "version": "1.9.3", @@ -3638,6 +4005,72 @@ ], "time": "2024-04-18T09:32:20+00:00" }, + { + "name": "symfony/filesystem", + "version": "v7.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "92a91985250c251de9b947a14bb2c9390b1a562c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/92a91985250c251de9b947a14bb2c9390b1a562c", + "reference": "92a91985250c251de9b947a14bb2c9390b1a562c", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v7.1.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-06-28T10:03:55+00:00" + }, { "name": "symfony/finder", "version": "v7.1.1", @@ -5408,6 +5841,78 @@ ], "time": "2024-06-28T08:00:31+00:00" }, + { + "name": "symfony/yaml", + "version": "v6.4.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "52903de178d542850f6f341ba92995d3d63e60c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/52903de178d542850f6f341ba92995d3d63e60c9", + "reference": "52903de178d542850f6f341ba92995d3d63e60c9", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<5.4" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v6.4.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-05-31T14:49:08+00:00" + }, { "name": "tijsverkoyen/css-to-inline-styles", "version": "v2.2.7", @@ -8495,77 +9000,6 @@ ], "time": "2023-02-07T11:34:05+00:00" }, - { - "name": "symfony/yaml", - "version": "v7.1.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "fa34c77015aa6720469db7003567b9f772492bf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/fa34c77015aa6720469db7003567b9f772492bf2", - "reference": "fa34c77015aa6720469db7003567b9f772492bf2", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "symfony/console": "<6.4" - }, - "require-dev": { - "symfony/console": "^6.4|^7.0" - }, - "bin": [ - "Resources/bin/yaml-lint" - ], - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Loads and dumps YAML files", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/yaml/tree/v7.1.1" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-05-31T14:57:53+00:00" - }, { "name": "ta-tikoma/phpunit-architecture-test", "version": "0.8.4", diff --git a/config/oauth.php b/config/oauth.php new file mode 100644 index 0000000..a94d919 --- /dev/null +++ b/config/oauth.php @@ -0,0 +1,7 @@ + env('OAUTH_CLIENT_ID'), + 'client_secret' => env('OAUTH_CLIENT_SECRET'), + 'discovery' => env('OAUTH_DISCOVERY_URL'), +]; diff --git a/database/migrations/2024_07_23_093251_create_assistants_table.php b/database/migrations/2024_07_23_093251_create_assistants_table.php new file mode 100644 index 0000000..88e439e --- /dev/null +++ b/database/migrations/2024_07_23_093251_create_assistants_table.php @@ -0,0 +1,36 @@ +id(); + + $table->string('name'); + $table->string('description'); + + // user_id + $table->unsignedBigInteger('user_id')->index(); + $table->foreign('user_id')->references('id')->on('users'); + + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('assistants'); + } +}; diff --git a/database/migrations/2024_07_23_093256_create_tools_table.php b/database/migrations/2024_07_23_093256_create_tools_table.php new file mode 100644 index 0000000..3c4587a --- /dev/null +++ b/database/migrations/2024_07_23_093256_create_tools_table.php @@ -0,0 +1,39 @@ +id(); + + $table->string('name'); + $table->string('description')->nullable(); + + $table->string('url'); + + $table->string('api_key')->nullable(); + + // user id + $table->unsignedBigInteger('user_id')->index(); + $table->foreign('user_id')->references('id')->on('users'); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('tools'); + } +}; diff --git a/database/migrations/2024_07_23_093301_create_chats_table.php b/database/migrations/2024_07_23_093301_create_chats_table.php new file mode 100644 index 0000000..2e36dfc --- /dev/null +++ b/database/migrations/2024_07_23_093301_create_chats_table.php @@ -0,0 +1,37 @@ +id(); + + $table->string('name'); + + $table->foreignId('assistant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('user_id')->constrained()->cascadeOnDelete(); + + // index + $table->index(['assistant_id', 'user_id']); + + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('chats'); + } +}; 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 new file mode 100644 index 0000000..27c5307 --- /dev/null +++ b/database/migrations/2024_07_23_132343_create_tool_functions_table.php @@ -0,0 +1,37 @@ +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_145223_create_assistant_tools_table.php b/database/migrations/2024_07_23_145223_create_assistant_tools_table.php new file mode 100644 index 0000000..3e68e9d --- /dev/null +++ b/database/migrations/2024_07_23_145223_create_assistant_tools_table.php @@ -0,0 +1,34 @@ +id(); + + $table->foreignId('assistant_id')->constrained()->cascadeOnDelete(); + $table->foreignId('tool_id')->constrained()->cascadeOnDelete(); + + // add index + $table->index(['assistant_id', 'tool_id']); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('assistant_tools'); + } +}; diff --git a/database/migrations/2024_07_23_151217_create_chat_histories_table.php b/database/migrations/2024_07_23_151217_create_chat_histories_table.php new file mode 100644 index 0000000..e4eb410 --- /dev/null +++ b/database/migrations/2024_07_23_151217_create_chat_histories_table.php @@ -0,0 +1,46 @@ +id(); + + $table->foreignId('chat_id')->constrained()->cascadeOnDelete(); + + $table->text('content'); + $table->string('role'); +// $table->string('model'); + + // input tokens + $table->integer('input_tokens')->default(null); + + // output tokens + $table->integer('output_tokens')->default(null); + + $table->integer('total_tokens')->default(null); + + // index + $table->index(['chat_id', 'role']); + + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('chat_histories'); + } +}; diff --git a/routes/web.php b/routes/web.php index 86a06c5..9e05733 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,7 +1,13 @@ group(function () { + Route::get('login', [AuthController::class, 'redirect'])->name('login'); + Route::get('callback', [AuthController::class, 'callback'])->name('oauth.callback'); + Route::post('logout', [AuthController::class, 'logout'])->name('logout'); }); + +Route::view('/', 'welcome')->name('home');