Skip to content
Merged
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
51 changes: 44 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Before building and running this project, ensure you have:
- **Node.js** (v18 or higher)
- **Corepack** (included with Node.js v16.10+, enables automatic Yarn management)
- **TypeScript** (v5.0 or higher)
- **OpenAI API Key** (for chat and image generation features)
- An **OpenAI API key** _or_ an **Azure OpenAI** resource (API key, endpoint, and a deployment) for chat and image generation features

### Setting up Corepack (Recommended)

Expand Down Expand Up @@ -97,32 +97,69 @@ yarn build

### 3. Run the applications (and set your API key)

Set your OpenAI API key so the apps can call the OpenAI APIs.
The apps can call either the **standard OpenAI API** or your own **Azure OpenAI**-hosted models. Configure whichever you have access to via environment variables — the same `VITE_OPENAI_API_KEY` variable is used in both cases (it holds either your OpenAI key or your Azure OpenAI key).

Option A — .env files (recommended for local development):

- Create `apps/promptions-chat/.env` with:
**Standard OpenAI**

- Create `apps/promptions-chat/.env` (and `apps/promptions-image/.env`) with:

```dotenv
VITE_OPENAI_API_KEY=your_openai_api_key_here
# Optional: override the chat model (defaults to gpt-4.1).
# The chat app supports GPT-4* and below; GPT-5* and later are NOT supported.
# VITE_OPENAI_MODEL=gpt-4.1
```

- Create `apps/promptions-image/.env` with:
**Azure OpenAI** (using your own hosted deployment)

- Create `apps/promptions-chat/.env` (and `apps/promptions-image/.env`) with:

```dotenv
VITE_OPENAI_API_KEY=your_openai_api_key_here
# Your Azure OpenAI resource key
VITE_OPENAI_API_KEY=your_azure_openai_key_here
# Your Azure OpenAI resource endpoint
VITE_OPENAI_BASE_URL=https://your-resource.openai.azure.com
# Required for Azure OpenAI
VITE_OPENAI_API_VERSION=2024-12-01-preview
# On Azure, this is your DEPLOYMENT NAME (not the underlying model id).
# The chat app supports GPT-4* family deployments and below; GPT-5* and later are NOT supported.
VITE_OPENAI_MODEL=your_chat_deployment_name
```

Option B — set it in your shell (PowerShell example):

```powershell
# Chat app
# Chat app — standard OpenAI
$env:VITE_OPENAI_API_KEY="your_openai_api_key_here" ; yarn workspace @promptions/promptions-chat dev

# Image app
# Chat app — Azure OpenAI
$env:VITE_OPENAI_API_KEY="your_azure_openai_key_here"
$env:VITE_OPENAI_BASE_URL="https://your-resource.openai.azure.com"
$env:VITE_OPENAI_API_VERSION="2024-12-01-preview"
$env:VITE_OPENAI_MODEL="your_chat_deployment_name"
yarn workspace @promptions/promptions-chat dev

# Image app (swap workspace name; same variable conventions apply)
$env:VITE_OPENAI_API_KEY="your_openai_api_key_here" ; yarn workspace @promptions/promptions-image dev
```

#### Configuration reference

Both apps read these `VITE_*` variables from their respective `.env` files.

| Variable | Description | Default |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | --------- |
| `VITE_OPENAI_API_KEY` | **Required.** Your OpenAI API key, or your Azure OpenAI resource key when `VITE_OPENAI_BASE_URL` is set. | _(unset)_ |
| `VITE_OPENAI_MODEL` | Chat model used for completions. On Azure OpenAI this is the **deployment name**. The image-generation model is selected in the UI. | `gpt-4.1` |
| `VITE_OPENAI_BASE_URL` | Custom endpoint. Set this to use Azure OpenAI (e.g. `https://your-resource.openai.azure.com`) or another OpenAI-compatible service. | _(unset)_ |
| `VITE_OPENAI_API_VERSION` | API version. **Required** when `VITE_OPENAI_BASE_URL` points at Azure OpenAI (e.g. `2024-12-01-preview`). | _(unset)_ |

When `VITE_OPENAI_BASE_URL` is set, the apps use the Azure OpenAI client; otherwise they use the standard OpenAI client.

> **Model compatibility:** The chat reference app supports **GPT-4\* family models and below** (e.g. `gpt-4`, `gpt-4.1`, `gpt-4o`). **GPT-5\* and later are not supported.** On Azure OpenAI, make sure the deployment named in `VITE_OPENAI_MODEL` targets a supported model.

Start the dev servers:

- Chat application (http://localhost:3003):
Expand Down
14 changes: 10 additions & 4 deletions apps/promptions-chat/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@
# Required: Set your API key
VITE_OPENAI_API_KEY=your_openai_api_key_here

# Optional: Set base URL for the OpenAI-compatible API endpoint (if blank, defaults to OpenAI API endpoint)
# VITE_OPENAI_BASE_URL=
# Optional: only set for Azure or other custom OpenAI-compatible endpoints.
# Omit for standard OpenAI API usage.
# VITE_OPENAI_BASE_URL=https://your-resource.openai.azure.com

# Optional: Set model to use (if blank, defaults to gpt-3.5-turbo)
# VITE_OPENAI_MODEL=
# Optional: API version is typically Azure-specific/custom-endpoint specific.
# Required when VITE_OPENAI_BASE_URL points at Azure OpenAI.
# VITE_OPENAI_API_VERSION=2024-12-01-preview

# Optional: override the chat model (defaults to gpt-4.1).
# Note that the Promptions Chat App does not support GPT-5* or later
# VITE_OPENAI_MODEL=gpt-4.1
48 changes: 32 additions & 16 deletions apps/promptions-chat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,45 @@ A modern chat interface built with React, Vite, Fluent UI, and OpenAI streaming

- Node.js 18+
- Yarn (workspace package manager)
- OpenAI API key
- An OpenAI API key, _or_ an Azure OpenAI resource (API key, endpoint, and a deployment)

### Installation

1. From the workspace root, install dependencies:

```bash
yarn install
```
```bash
yarn install
```

2. Navigate to the chat app directory:

```bash
cd apps/promptions-chat
```
```bash
cd apps/promptions-chat
```

3. Copy the environment file and add your OpenAI API key:
3. Copy the environment file and configure your provider:

```bash
cp .env.example .env
```
```bash
cp .env.example .env
```

Edit `.env` and add your OpenAI API key:
**Standard OpenAI** — edit `.env` and add your OpenAI API key:

```
VITE_OPENAI_API_KEY=your_api_key_here
```
```
VITE_OPENAI_API_KEY=your_api_key_here
```

**Azure OpenAI** — to use your own Azure-hosted deployment, set:

```
VITE_OPENAI_API_KEY=your_azure_openai_key_here
VITE_OPENAI_BASE_URL=https://your-resource.openai.azure.com
VITE_OPENAI_API_VERSION=2024-12-01-preview
# On Azure, VITE_OPENAI_MODEL is your DEPLOYMENT NAME (not a model id).
VITE_OPENAI_MODEL=your_chat_deployment_name
```

When `VITE_OPENAI_BASE_URL` is set, the app uses the Azure OpenAI client; otherwise it uses the standard OpenAI client.

### Development

Expand Down Expand Up @@ -75,9 +87,13 @@ yarn typecheck
- **React 18** - Modern React with hooks
- **Vite** - Fast build tool and dev server
- **Fluent UI** - Microsoft's design system
- **OpenAI API** - GPT-3.5-turbo with streaming
- **OpenAI / Azure OpenAI API** - Streaming chat completions (defaults to `gpt-4.1`)
- **TypeScript** - Full type safety

## Model compatibility

The chat app supports **GPT-4\* family models and below** (e.g. `gpt-4`, `gpt-4.1`, `gpt-4o`). **GPT-5\* and later are not supported.** When using Azure OpenAI, ensure the deployment named in `VITE_OPENAI_MODEL` targets a supported model.

## Security Notes

⚠️ **Important**: This demo uses `dangerouslyAllowBrowser: true` for the OpenAI client, which exposes your API key in the browser. In a production application, you should:
Expand Down
26 changes: 17 additions & 9 deletions apps/promptions-chat/src/services/ChatService.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import OpenAI from "openai";
import OpenAI, { AzureOpenAI } from "openai";

interface ChatMessage {
role: "user" | "assistant" | "system";
Expand All @@ -12,21 +12,29 @@ export class ChatService {
constructor() {
// In a real application, you'd want to handle the API key more securely
// For development, you can set VITE_OPENAI_API_KEY in your .env file
const apiKey = import.meta.env.VITE_OPENAI_API_KEY || process.env.OPENAI_API_KEY;
const baseURL = import.meta.env.VITE_OPENAI_BASE_URL || process.env.OPENAI_BASE_URL;
this.model = import.meta.env.VITE_OPENAI_MODEL || process.env.OPENAI_MODEL || "gpt-3.5-turbo";
const apiKey = import.meta.env.VITE_OPENAI_API_KEY;

if (!apiKey) {
throw new Error(
"OpenAI API key is required. Please set VITE_OPENAI_API_KEY in your environment variables.",
);
}

this.client = new OpenAI({
apiKey,
baseURL,
dangerouslyAllowBrowser: true, // Only for demo purposes - use a backend in production
});
const baseURL = import.meta.env.VITE_OPENAI_BASE_URL;
const apiVersion = import.meta.env.VITE_OPENAI_API_VERSION;
this.model = import.meta.env.VITE_OPENAI_MODEL || "gpt-4.1";

this.client = baseURL
? new AzureOpenAI({
apiKey,
endpoint: baseURL,
apiVersion,
dangerouslyAllowBrowser: true, // Only for demo purposes - use a backend in production
})
: new OpenAI({
apiKey,
dangerouslyAllowBrowser: true, // Only for demo purposes - use a backend in production
});
}

async streamChat(
Expand Down
3 changes: 3 additions & 0 deletions apps/promptions-chat/src/vite-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

interface ImportMetaEnv {
readonly VITE_OPENAI_API_KEY: string;
readonly VITE_OPENAI_BASE_URL?: string;
readonly VITE_OPENAI_API_VERSION?: string;
readonly VITE_OPENAI_MODEL?: string;
// more env variables...
}

Expand Down
14 changes: 10 additions & 4 deletions apps/promptions-image/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@
# Required: Set your API key
VITE_OPENAI_API_KEY=your_openai_api_key_here

# Optional: Set base URL for the OpenAI-compatible API endpoint (if blank, defaults to OpenAI API endpoint)
# VITE_OPENAI_BASE_URL=
# Optional: only set for Azure or other custom OpenAI-compatible endpoints.
# Omit for standard OpenAI API usage.
# VITE_OPENAI_BASE_URL=https://your-resource.openai.azure.com

# Optional: Set model to use (if blank, defaults to gpt-3.5-turbo)
# VITE_OPENAI_MODEL=
# Optional: API version is typically Azure-specific/custom-endpoint specific.
# Required when VITE_OPENAI_BASE_URL points at Azure OpenAI.
# VITE_OPENAI_API_VERSION=2024-12-01-preview

# Optional: override the chat model used for prompt-related completions (defaults to gpt-4.1).
# The image-generation model is selected in the UI.
# VITE_OPENAI_MODEL=gpt-4.1
26 changes: 17 additions & 9 deletions apps/promptions-image/src/services/ImageService.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
import OpenAI from "openai";
import OpenAI, { AzureOpenAI } from "openai";
import { ImageGenerationParams, GeneratedImage } from "../types";

export class ImageService {
private client: OpenAI;
private chatModel: string;

constructor() {
const apiKey = import.meta.env.VITE_OPENAI_API_KEY || process.env.OPENAI_API_KEY;
const baseURL = import.meta.env.VITE_OPENAI_BASE_URL || process.env.OPENAI_BASE_URL;
this.chatModel = import.meta.env.VITE_OPENAI_MODEL || process.env.OPENAI_MODEL || "gpt-3.5-turbo";
const apiKey = import.meta.env.VITE_OPENAI_API_KEY;

if (!apiKey) {
throw new Error(
"OpenAI API key is required. Please set VITE_OPENAI_API_KEY in your environment variables.",
);
}

this.client = new OpenAI({
apiKey,
baseURL,
dangerouslyAllowBrowser: true, // Only for demo purposes - use a backend in production
});
const baseURL = import.meta.env.VITE_OPENAI_BASE_URL;
const apiVersion = import.meta.env.VITE_OPENAI_API_VERSION;
this.chatModel = import.meta.env.VITE_OPENAI_MODEL || "gpt-4.1";

this.client = baseURL
? new AzureOpenAI({
apiKey,
endpoint: baseURL,
apiVersion,
dangerouslyAllowBrowser: true, // Only for demo purposes - use a backend in production
})
: new OpenAI({
apiKey,
dangerouslyAllowBrowser: true, // Only for demo purposes - use a backend in production
});
}

async generateImage(params: ImageGenerationParams, options?: { signal?: AbortSignal }): Promise<GeneratedImage[]> {
Expand Down
3 changes: 3 additions & 0 deletions apps/promptions-image/src/vite-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

interface ImportMetaEnv {
readonly VITE_OPENAI_API_KEY: string;
readonly VITE_OPENAI_BASE_URL?: string;
readonly VITE_OPENAI_API_VERSION?: string;
readonly VITE_OPENAI_MODEL?: string;
// more env variables...
}

Expand Down
Loading