Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,5 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you're referencing the .gitignore file and mentioning the addition of the following lines:

model-service/.env
model-service/.env

Explanation in context:
These lines tell Git to ignore the .env file located in the model-service directory. The .env file typically contains environment variables, which often include sensitive information like API keys, database credentials, or other configuration details that should not be committed to source control.

Code Review Feedback & Suggestions:

  1. Duplication:

    • You have the same line twice. You only need one entry for model-service/.env. Remove the duplicate to keep the .gitignore clean.
  2. Security:

    • Good practice to ignore .env files. This helps prevent accidentally pushing sensitive data to the repository.
  3. Clarity:

    • If you expect .env files in multiple subdirectories, consider using a pattern like **/.env. However, if you only want to ignore it in model-service, your current approach is correct.
  4. Team Communication:

    • Remind your team that ignoring .env means everyone needs to create their own local version or use a sample file (like .env.example) to share the required variables.

Suggested Correction:
Just keep one entry:

model-service/.env

Summary:
Your intent is good for security and standard practice. Just remove the duplicate line for neatness. If you need further help with .env handling or best practices, let me know!

model-service/.env

5 changes: 5 additions & 0 deletions model-service/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
OPENAI_BASE_URL=https://api.openai.com/v1
OPENAI_API_KEY=sk-REPLACE_ME
MODEL_NAME=gpt-4o-mini
PORT=7071

5 changes: 5 additions & 0 deletions model-service/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package-lock.json
node_modules/
.env
.DS_Store

2 changes: 2 additions & 0 deletions model-service/Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
web: node server.js

16 changes: 16 additions & 0 deletions model-service/ecosystem.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module.exports = {
apps: [
{
name: 'reentry-model-service',
script: 'server.js',
instances: 1,
exec_mode: 'fork',
env: {
// server.js loads dotenv; these are optional overrides
PORT: process.env.PORT || 7071,
},
watch: false,
},
],
};

20 changes: 20 additions & 0 deletions model-service/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "reentry-model-service",
"version": "1.0.0",
"private": true,
"main": "server.js",
"license": "UNLICENSED",
"scripts": {
"dev": "node server.js",
"start": "node server.js",
"pm2": "pm2 start ecosystem.config.js"
},
"dependencies": {
"dotenv": "^16.4.5",
"express": "^4.19.2",
"node-fetch": "^2.7.0"
},
"engines": {
"node": ">=18"
}
}
64 changes: 64 additions & 0 deletions model-service/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const express = require('express');
const fetch = require('node-fetch');
const dotenv = require('dotenv');

dotenv.config();

const app = express();
app.use(express.json());

const PORT = process.env.PORT || 7071;
const OPENAI_BASE_URL = (process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1').replace(/\/+$/, '');
const OPENAI_API_KEY = process.env.OPENAI_API_KEY || '';
const MODEL_NAME = process.env.MODEL_NAME || 'gpt-4o-mini';

// Health endpoint
app.get('/health', (_req, res) => {
res.json({ ok: true, model: MODEL_NAME, base: OPENAI_BASE_URL });
});

// Generate endpoint - forwards to provider-compatible chat/completions
app.post('/generate', async (req, res) => {
try {
if (!OPENAI_API_KEY) {
return res.status(400).json({ error: 'Missing OPENAI_API_KEY in environment' });
}

const body = req.body || {};
const messages = body.messages;
const model = body.model || MODEL_NAME;
const extra = body.extra || {}; // allow optional pass-through params

if (!Array.isArray(messages) || messages.length === 0) {
return res.status(400).json({ error: 'Body must include messages: [{ role, content }]' });
}

const url = `${OPENAI_BASE_URL}/chat/completions`;

const providerResp = await fetch(url, {
method: 'POST',
headers: {
'Authorization': `Bearer ${OPENAI_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ model, messages, ...extra })
});

const data = await providerResp.json();

if (!providerResp.ok) {
// Pass through provider error
return res.status(providerResp.status).json({ error: data.error || data });
}

const text = data?.choices?.[0]?.message?.content || '';
return res.json({ text });
} catch (err) {
return res.status(500).json({ error: 'Upstream error', detail: String(err && err.message || err) });
}
});

app.listen(PORT, () => {
console.log(`model-service listening on http://localhost:${PORT}`);
});