Compare commits

...

8 Commits

Author SHA1 Message Date
hackerESQ 997b5420ee Merge pull request #44 from investbrainapp/create-docker-image
Use the investbrainapp/investbrain docker image
2024-12-17 18:28:03 -06:00
hackerESQ 643bbe3af2 wait for db to be ready in order to migrate 2024-12-16 21:54:59 -06:00
hackerESQ f85f0f19b9 wip 2024-12-16 21:33:45 -06:00
hackerESQ 3f9a1bafa0 Merge pull request #37 from investbrainapp/feat-use-openai-compatible-endpoints
Feat use openai compatible endpoints
2024-12-06 16:10:54 -06:00
hackerESQ 6f72a03ecf fix: specifically use factory import 2024-12-06 16:10:27 -06:00
hackerESQ 5b8e4c634e fix: remove validation which could prevent selfhosting w ollama 2024-12-06 16:09:03 -06:00
hackerESQ 70c3f7162e Merge pull request #36 from investbrainapp/feat-use-openai-compatible-endpoints
feat: adds ollama support
2024-12-06 16:02:13 -06:00
hackerESQ cb9199431a feat: adds ollama support 2024-12-06 16:01:53 -06:00
13 changed files with 473 additions and 517 deletions
+1 -1
View File
@@ -52,7 +52,7 @@ QUEUE_CONNECTION=redis
CACHE_STORE=redis
REDIS_CLIENT=predis
REDIS_HOST=127.0.0.1
REDIS_HOST=investbrain-redis
REDIS_PATH=/tmp/database_server.sock
REDIS_PASSWORD=null
REDIS_PORT=6379
+6 -3
View File
@@ -20,7 +20,7 @@ Investbrain is a smart open-source investment tracker that helps you manage, tra
## Under the hood
Investbrain is a Laravel PHP web application that leverages Livewire and Tailwind for its frontend. Most databases should work, including MySQL and SQLite. Out of the box, we feature three market data providers: [Yahoo Finance](https://finance.yahoo.com/), [Finnhub](https://finnhub.io/pricing-stock-api-market-data), and [Alpha Vantage](https://www.alphavantage.co/support/). But we also offer an extensible market data provider interface for intrepid developers to create their own! We also offer an integration with OpenAI's LLMs for our ["chat with your holdings"](#chat-with-your-holdings) capability. Finally, of course we have robust support for i18n, a11y, and dark mode.
Investbrain is a Laravel PHP web application that leverages Livewire and Tailwind for its frontend. Most databases should work, including MySQL and SQLite. Out of the box, we feature three market data providers: [Yahoo Finance](https://finance.yahoo.com/), [Finnhub](https://finnhub.io/pricing-stock-api-market-data), and [Alpha Vantage](https://www.alphavantage.co/support/). But we also offer an extensible market data provider interface for intrepid developers to create their own! We also offer an integration with OpenAI for our ["chat with your holdings"](#chat-with-your-holdings) capability. Finally, of course we have robust support for i18n, a11y, and dark mode.
## Self hosting
@@ -58,7 +58,9 @@ Investbrain offers an AI powered chat assistant that is grounded on *your* inves
When self-hosting, you can enable the chat assistant by configuring your OpenAI Secret Key and Organization ID in your [.env](https://github.com/investbrainapp/investbrain/blob/main/.env.example) file. Navigate to OpenAI to [create your keys](https://platform.openai.com/api-keys).
Always keep in mind the limitations of large language models. When in doubt, consult a licensed investment advisor.
If you are self-hosting your own large language models ("LLMs") that expose an OpenAI compatible API (e.g. [Ollama](https://ollama.com/blog/openai-compatibility)), you can update the `OPENAI_BASE_URI` configuration to your self-hosted instance. Ensure you also update the `OPENAI_MODEL` to an available model.
Always keep in mind the limitations of LLMs. When in doubt, consult a licensed investment advisor.
## Market data providers
@@ -133,11 +135,12 @@ There are several optional configurations available when installing using the re
| AI_CHAT_ENABLED | Whether to enable AI chat features | `false` |
| OPENAI_API_KEY | OpenAI secret key (required for AI chat) | `null` |
| OPENAI_ORGANIZATION | OpenAI org id (required for AI chat) | `null` |
| OPENAI_MODEL | The selected LLM used for AI chat | gpt-4o |
| OPENAI_BASE_URI | The URI for your self-hosted LLM | api.openai.com/v1 |
| DAILY_CHANGE_TIME | The time of day to capture daily change | 23:00 |
| REGISTRATION_ENABLED | Whether to enable registration of new users | `true` |
> Note: These options affect the [docker-compose.yml](https://github.com/investbrainapp/investbrain/blob/main/docker-compose.yml) file, so if you decide to make any changes to these default configurations, you'll have to restart the Docker containers before your changes take effect.
## Updating
+1 -1
View File
@@ -16,7 +16,7 @@
"livewire/livewire": "^3.5",
"livewire/volt": "^1.6",
"maatwebsite/excel": "^3.1",
"openai-php/laravel": "^0.10.2",
"openai-php/client": "^0.10.3",
"predis/predis": "^2.2",
"robsontenorio/mary": "^1.35",
"scheb/yahoo-finance-api": "^4.11",
Generated
+415 -444
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -27,5 +27,6 @@ return [
'request_timeout' => env('OPENAI_REQUEST_TIMEOUT', 30),
//
'base_uri' => env('OPENAI_BASE_URI', 'api.openai.com/v1'),
'model' => env('OPENAI_MODEL', 'gpt-4o'),
];
+12 -3
View File
@@ -3,9 +3,7 @@ networks:
driver: bridge
services:
app:
build:
context: .
dockerfile: docker/Dockerfile
image: investbrainapp/investbrain:latest
container_name: investbrain-app
restart: unless-stopped
tty: true
@@ -15,8 +13,18 @@ services:
- .:/var/www/app:delegated
depends_on:
- mysql
- redis
networks:
- investbrain-network
redis:
image: redis:alpine
container_name: investbrain-redis
restart: unless-stopped
tty: true
networks:
- investbrain-network
volumes:
- investbrain-redis:/data
nginx:
image: nginx:alpine
container_name: investbrain-nginx
@@ -46,4 +54,5 @@ services:
networks:
- investbrain-network
volumes:
investbrain-redis:
investbrain-mysql:
-1
View File
@@ -1 +0,0 @@
dump.rdb
-47
View File
@@ -1,47 +0,0 @@
FROM php:8.3-fpm
ENV DEBIAN_FRONTEND noninteractive
# Set the working directory
COPY . /var/www/app
WORKDIR /var/www/app
# Install common php extension dependencies
RUN apt-get update && apt-get install -y \
libfreetype-dev \
libjpeg62-turbo-dev \
libpng-dev \
zlib1g-dev \
libzip-dev \
unzip \
libicu-dev \
git \
curl \
redis \
supervisor \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) \
gd \
zip \
pdo_mysql \
mysqli \
intl
# Install Node.js and npm
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs \
&& npm install -g npm@latest
# Copy over supervisor configuration
COPY ./docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Update permissions
RUN chown -R www-data:www-data . \
&& chmod -R 775 ./storage \
&& chmod +x ./docker/entrypoint.sh
# install composer
COPY --from=composer:2.6.5 /usr/bin/composer /usr/local/bin/composer
# Run everything else
CMD ["./docker/entrypoint.sh"]
Executable → Regular
+14 -4
View File
@@ -9,9 +9,6 @@ if [ ! -f ".env" ]; then
cp .env.example .env
fi
echo "====================== Checking for updates... ====================== "
/usr/bin/git pull
echo "====================== Installing Composer dependencies... ====================== "
/usr/local/bin/composer install
@@ -38,7 +35,20 @@ echo "====================== Installing NPM dependencies and building frontend..
/usr/bin/npm run build
echo "====================== Running migrations... ====================== "
/usr/local/bin/php artisan migrate --force
run_migrations() {
/usr/local/bin/php artisan migrate --force
}
RETRIES=30
DELAY=5
until run_migrations; do
RETRIES=$((RETRIES-1))
if [ $RETRIES -le 0 ]; then
echo "Database is not ready after multiple attempts. Exiting..."
exit 1
fi
echo "Waiting for database to be ready... retrying in $DELAY seconds."
sleep $DELAY
done
echo "====================== Spinning up Supervisor daemon... ====================== "
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
-2
View File
@@ -1,2 +0,0 @@
# Redis RDB and AOF file location
dir /var/www/app/docker
-7
View File
@@ -11,13 +11,6 @@ autorestart=true
stdout_logfile=/var/log/supervisor/php.log
stderr_logfile=/var/log/supervisor/php_error.log
[program:redis]
command=redis-server /var/www/app/docker/redis.conf
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/redis.log
stderr_logfile=/var/log/supervisor/redis_error.log
[program:scheduler]
command=php artisan schedule:work
autorestart=true
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "investbrain",
"name": "app",
"lockfileVersion": 3,
"requires": true,
"packages": {
@@ -5,7 +5,7 @@ use App\Models\AiChat;
use App\Models\Holding;
use Illuminate\Database\Eloquent\Model;
use Livewire\Volt\Component;
use OpenAI\Laravel\Facades\OpenAI;
use OpenAI\Factory;
use OpenAI\Responses\StreamResponse;
new class extends Component {
@@ -67,7 +67,9 @@ new class extends Component {
{
try {
$stream = OpenAI::chat()->createStreamed([
$client = $this->createOpenAiClient();
$stream = $client->chat()->createStreamed([
'model' => config('openai.model'),
'messages' => [
['role' => 'system', 'content' => "Today's date is "
@@ -104,7 +106,9 @@ new class extends Component {
public function generateSuggestedPrompts(): void
{
try {
$suggested_prompts = OpenAI::chat()->create([
$client = $this->createOpenAiClient();
$suggested_prompts = $client->chat()->create([
'model' => config('openai.model'),
'response_format' => [
'type' => 'json_schema',
@@ -192,6 +196,21 @@ new class extends Component {
return false;
}
private function createOpenAiClient()
{
$apiKey = config('openai.api_key');
$organization = config('openai.organization');
$baseUri = config('openai.base_uri');
return OpenAI::factory()
->withApiKey($apiKey)
->withOrganization($organization)
->withHttpHeader('OpenAI-Beta', 'assistants=v2')
->withHttpClient(new \GuzzleHttp\Client(['timeout' => config('openai.request_timeout', 30)]))
->withBaseUri($baseUri)
->make();
}
}; ?>
<div