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
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,12 @@ the response text.
The generated app uses `tsc` and `node` directly, so first-run installs work
with pnpm 11 without approving ignored dependency build scripts.

To point at a non-default local endpoint:
To point at a non-default local endpoint, set either the server origin or an
OpenAI-compatible `/v1` base URL:

```bash
QVAC_BASE_URL=http://localhost:8001 pnpm dev
QVAC_BASE_URL=http://localhost:8001/v1 pnpm dev
```

## Troubleshooting
Expand All @@ -74,10 +76,12 @@ For the default endpoint:
curl http://localhost:8000/v1/chat/completions
```

If the server is on another port or host, restart the app with `QVAC_BASE_URL`:
If the server is on another port or host, restart the app with `QVAC_BASE_URL`.
Both origin-style and OpenAI-style `/v1` base URLs are accepted:

```bash
QVAC_BASE_URL=http://localhost:8001 pnpm dev
QVAC_BASE_URL=http://localhost:8001/v1 pnpm dev
```

## Local development
Expand Down
9 changes: 8 additions & 1 deletion src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ Set \`QVAC_BASE_URL\` to use a different local endpoint.
"src/index.ts",
`const baseUrl = process.env.QVAC_BASE_URL ?? "http://localhost:8000";

function chatCompletionsUrl(rawBaseUrl: string): string {
const normalized = rawBaseUrl.replace(/\\/+$/, "");
return normalized.endsWith("/v1")
? \`\${normalized}/chat/completions\`
: \`\${normalized}/v1/chat/completions\`;
}

interface ChatCompletionResponse {
choices?: Array<{
message?: {
Expand All @@ -140,7 +147,7 @@ interface ChatCompletionResponse {
}

async function main(): Promise<void> {
const response = await fetch(\`\${baseUrl}/v1/chat/completions\`, {
const response = await fetch(chatCompletionsUrl(baseUrl), {
method: "POST",
headers: {
"content-type": "application/json",
Expand Down
3 changes: 3 additions & 0 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ describe("create-qvac-app", () => {
expect(readFileSync(join(appDirectory, "src/index.ts"), "utf8")).toContain(
"QVAC_BASE_URL",
);
expect(readFileSync(join(appDirectory, "src/index.ts"), "utf8")).toContain(
'normalized.endsWith("/v1")',
);

const packageJson = JSON.parse(
readFileSync(join(appDirectory, "package.json"), "utf8"),
Expand Down
Loading