Skip to content

Feat/zero config#36

Open
vi70x3 wants to merge 5 commits into
mainfrom
feat/zero-config
Open

Feat/zero config#36
vi70x3 wants to merge 5 commits into
mainfrom
feat/zero-config

Conversation

@vi70x3

@vi70x3 vi70x3 commented Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Summary by Sourcery

Introduce zero-configuration deployment for llm-proxy and dynamic topology-based worker capacity, removing reliance on PROXY_IP_COUNT and simplifying setup and deployment flows.

Enhancements:

  • Refactor IP pool capacity management to derive worker count solely from dynamic topology and deprecate the PROXY_IP_COUNT environment variable.
  • Add automatic topology reconciliation services and scripts that compute required worker count from API keys and redeploy llm-proxy when drift is detected.
  • Add a deploy-proxy script and associated package scripts to auto-deploy llm-proxy to Cloudflare Workers and capture the workers.dev URL into configuration.
  • Enhance analytics client types for stronger typing and safer data handling in the dashboard.
  • Refine server startup to initialize and reconcile topology asynchronously without blocking startup, and adjust verification tooling to validate topology and configuration more explicitly.

Build:

  • Add deploy-proxy and reconcile-topology scripts, wiring them into package.json and integrating deploy-proxy into the setup flow for automatic proxy deployment.
  • Update setup, install, and verification scripts to support non-interactive operation, dry-run modes, and clearer post-install and configuration diagnostics.

Documentation:

  • Rewrite README quick start to describe zero-interactive installation, add advanced configuration and environment variable documentation, and update topology discovery docs to reflect dynamic topology and removal of PROXY_IP_COUNT.
  • Add internal zero-configuration deployment design, requirements, and task specs under .roo/specs for implementation guidance and traceability.

Tests:

  • Update IP pool capacity tests to rely on mock topology instead of PROXY_IP_COUNT, and expand coverage for topology-only worker count behavior and PROXY_IP_COUNT deprecation semantics.

vi70x3 added 4 commits June 8, 2026 20:44
…aling

- setup.ts: non-interactive default mode with --interactive flag for old behavior
- deploy-proxy.ts: deploy llm-proxy to workers.dev and capture assigned URL
- reconcile-topology.ts: standalone drift detection and repair for proxy topology
- capacityService.ts: shared getRequiredWorkerCount() from database
- topologyReconciliation.ts: active self-healing at startup, blocks on failure
- llm-proxy router: dynamic endpoint derivation via Web Crypto API SHA-256
- Eliminated PROXY_IP_COUNT and ROUTER_DOMAIN user-facing configuration
- Updated install.sh, install.ps1, verify-deploy.ts, README.md, .env.example
- Deleted llm-proxy/src/generated/topology.ts (replaced by dynamic endpoint)
… parser, sort TOML keys, type-safe sortModels
@sourcery-ai

sourcery-ai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implements zero-configuration deployment and dynamic proxy topology: setup now non-interactive and auto-deploys llm-proxy via a new deploy-proxy script, topology and IP capacity rely solely on dynamic topology (deprecating PROXY_IP_COUNT and ROUTER_DOMAIN), startup includes automatic topology reconciliation based on API key counts, analytics typings and README docs are updated, and new design/spec documentation is added.

Sequence diagram for startup topology reconciliation and self-healing

sequenceDiagram
  participant Main as server index.ts
  participant Topology as proxyTopology
  participant ReconSvc as topologyReconciliation
  participant Capacity as capacityService
  participant ReconScript as reconcile-topology.ts
  participant Deploy as deploy-proxy.ts
  participant CF as CloudflareWorkers

  Main->>Topology: initialize()
  Main->>ReconSvc: reconcileTopology()
  ReconSvc->>Topology: getWorkerCount()
  ReconSvc->>Topology: isDynamicTopologyAvailable()
  ReconSvc->>Capacity: getRequiredWorkerCount()
  alt drift detected
    ReconSvc->>ReconScript: spawn("npx tsx reconcile-topology.ts")
    ReconScript->>Capacity: getRequiredWorkerCount()
    ReconScript->>Deploy: deployProxy(requiredCount)
    Deploy->>CF: runWranglerDeploy(proxy workers)
    Deploy->>CF: runWranglerDeploy(router)
    Deploy->>Deploy: updateEnvKey(LLM_PROXY_URL)
  else no drift
    ReconSvc-->>Main: no-op
  end
Loading

File-Level Changes

Change Details Files
IP pool capacity and tests now use dynamic topology workerCount exclusively, fully deprecating PROXY_IP_COUNT and static env-based capacity.
  • Remove getIpCount and PROXY_IP_COUNT-based fallback from getWorkerCount, making dynamic topology the only source of worker count and returning 0 when unavailable.
  • Simplify isStickyRoutingEnabled to rely solely on isDynamicTopologyAvailable, and log a deprecation warning if PROXY_IP_COUNT is set.
  • Update ipPoolCapacity tests to configure capacity via _setMockTopology and resetTopology instead of mutating process.env.PROXY_IP_COUNT, including renaming/clarifying test descriptions and making type-safe assertions on allocated results.
  • Clarify cleanupExpired semantics as a no-op and adjust related tests accordingly.
server/src/services/ipPoolCapacity.ts
server/src/__tests__/services/ipPoolCapacity.test.ts
Setup and deployment are now zero-config: setup.ts becomes non-interactive by default and auto-runs a new deploy-proxy workflow, with supporting scripts for reconciliation and verification.
  • Extend setup.ts with --interactive, --dry-run, and --regenerate semantics, auto-generating AUTH_KEY when non-interactive, skipping ROUTER_DOMAIN/LLM_PROXY_URL prompts, and invoking deploy-proxy in non-interactive runs while updating next-step messaging.
  • Add deploy-proxy.ts to generate per-worker and router Wrangler TOML, deploy proxy and router workers with retries, capture the router workers.dev URL from wrangler output, update PROXY_COUNT in llm-proxy/.env, and write LLM_PROXY_URL to the root .env, with dry-run support and summarized results.
  • Introduce reconcile-topology.ts and server/src/services/topologyReconciliation.ts to compute required worker count from the database (via new capacityService.getRequiredWorkerCount), compare it with the current topology.workerCount, and when drifted, redeploy llm-proxy with the correct worker count, callable both as a script and at server startup.
  • Update verify-deploy.ts checks and dry-run output to validate LLM_PROXY_URL presence and PROXY_IP_COUNT deprecation, renumbering checks, and clarifying fallback reporting; wire new npm scripts deploy-proxy and reconcile-topology into package.json and adjust install.sh/install.ps1 messaging to reflect automatic deployment.
  • Introduce server/src/services/capacityService.ts as a single source of truth for required worker count based on enabled API key distribution.
scripts/setup.ts
scripts/deploy-proxy.ts
scripts/reconcile-topology.ts
server/src/services/topologyReconciliation.ts
server/src/services/capacityService.ts
scripts/verify-deploy.ts
package.json
install.sh
install.ps1
Documentation is expanded to describe zero-config install, advanced configuration, environment variables, and dynamic proxy topology, with internal design/spec docs for the new deployment model.
  • Rewrite README quick start to a four-step zero-config flow (Node.js, wrangler login, install script, pnpm dev), add an Advanced configuration section describing setup flags and manual commands (setup, deploy-proxy, reconcile-topology, verify), and move environment variables and topology discovery into dedicated sections that explain dynamic topology as the primary source and removal of PROXY_IP_COUNT from capacity.
  • Clarify that LLM_PROXY_URL enables topology discovery and that if unset, IP capacity is disabled; note that PROXY_COUNT in llm-proxy/.env is managed by freellmapi and should not be edited manually.
  • Add .roo/specs/zero-configuration-deployment/{requirements,design,tasks}.md documenting requirements, architecture, task breakdown, and verification checklist for the zero-configuration deployment initiative.
README.md
.roo/specs/zero-configuration-deployment/requirements.md
.roo/specs/zero-configuration-deployment/design.md
.roo/specs/zero-configuration-deployment/tasks.md
Analytics dashboard code is tightened with explicit types for API responses to improve type safety and readability.
  • Introduce explicit interfaces (AnalyticsSummary, PlatformRow, TimelineRow, ModelRow, ErrorRow) and use them in useQuery calls instead of unknown/any.
  • Simplify sortModels signature to operate on ModelRow[], and narrow map usage for byPlatformWithFailures and error rows to their typed shapes.
client/src/pages/AnalyticsPage.tsx
Server startup now performs topology reconciliation and small UI/docs cosmetic fixes are applied.
  • Wire reconcileTopology into server/src/index.ts main startup sequence after initTopology to trigger background reconciliation on boot.
  • Tidy minor README ASCII diagram indentation to keep the router block aligned with surrounding text.
server/src/index.ts
README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a Zero-Configuration Deployment flow for freellmapi, automating secret generation, Cloudflare Workers deployment, and topology reconciliation on startup based on enabled database API keys. The review feedback is highly actionable and identifies critical issues that must be addressed: a potential process leak in the reconciliation script due to an unclosed SQLite connection, a cross-platform spawn failure on Windows, a specification violation where ROUTER_DOMAIN is not written to the proxy environment, and several unused imports that could break compilation under strict TypeScript configurations.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +176 to +183
async function main(): Promise<void> {
try {
await reconcile();
} catch (err) {
console.error("[reconcile] Fatal error:", err);
process.exit(1);
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

The script initializes the database connection via initDb(), which keeps the SQLite connection open. Without an explicit process.exit(0) on success, the process will hang indefinitely in the background when spawned by the server, leading to process leaks. Add process.exit(0) after await reconcile() to ensure clean termination.

Suggested change
async function main(): Promise<void> {
try {
await reconcile();
} catch (err) {
console.error("[reconcile] Fatal error:", err);
process.exit(1);
}
}
async function main(): Promise<void> {
try {
await reconcile();
process.exit(0);
} catch (err) {
console.error("[reconcile] Fatal error:", err);
process.exit(1);
}
}

Comment on lines +47 to +50
const child = spawn("npx", ["tsx", scriptPath], {
cwd: projectRoot,
stdio: "inherit",
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

On Windows platforms, spawning npx directly without shell: true will fail with an ENOENT error because npx is a batch file (npx.cmd). Since Windows support is explicitly required (via install.ps1), add shell: true to make the spawn command cross-platform.

Suggested change
const child = spawn("npx", ["tsx", scriptPath], {
cwd: projectRoot,
stdio: "inherit",
});
const child = spawn("npx", ["tsx", scriptPath], {
cwd: projectRoot,
stdio: "inherit",
shell: true,
});

Comment thread scripts/deploy-proxy.ts Outdated
Comment on lines +379 to +382
// Write LLM_PROXY_URL to .env
console.log("\n📝 Writing LLM_PROXY_URL to .env...");
updateEnvKey(frellmapiEnvPath, "LLM_PROXY_URL", routerUrl, false);
console.log(` ✅ LLM_PROXY_URL written to .env`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

According to the requirements (REQ-Z3.3 and REQ-Z3.5), the captured router URL must be written to both freellmapi-alpha/.env as LLM_PROXY_URL and to llm-proxy/.env as ROUTER_DOMAIN (without the https:// prefix). Currently, ROUTER_DOMAIN is not being written, which violates the specification and could break manual deployments or backward compatibility.

Suggested change
// Write LLM_PROXY_URL to .env
console.log("\n📝 Writing LLM_PROXY_URL to .env...");
updateEnvKey(frellmapiEnvPath, "LLM_PROXY_URL", routerUrl, false);
console.log(` ✅ LLM_PROXY_URL written to .env`);
// Write LLM_PROXY_URL to .env and ROUTER_DOMAIN to llm-proxy/.env
console.log("\n📝 Writing LLM_PROXY_URL and ROUTER_DOMAIN to .env files...");
updateEnvKey(frellmapiEnvPath, "LLM_PROXY_URL", routerUrl, false);
const bareDomain = routerUrl.replace(/^https?:\/\//, "");
updateEnvKey(llmProxyEnvPath, "ROUTER_DOMAIN", bareDomain, false);
console.log(" ✅ LLM_PROXY_URL and ROUTER_DOMAIN written to .env files");

Comment thread scripts/setup.ts Outdated
import { fileURLToPath } from 'node:url';
import readline from 'node:readline';
import { parseEnvFile, readEnvFileRaw, writeEnvFile } from './lib/env.js';
import { parseEnvFile, readEnvFileRaw, writeEnvFile, updateEnvKey } from './lib/env.js';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

updateEnvKey is imported from ./lib/env.js but is never used in this file. If noUnusedLocals is enabled in tsconfig.json, this unused import will cause a compilation error and break the build.

Suggested change
import { parseEnvFile, readEnvFileRaw, writeEnvFile, updateEnvKey } from './lib/env.js';
import { parseEnvFile, readEnvFileRaw, writeEnvFile } from './lib/env.js';

Comment thread scripts/reconcile-topology.ts Outdated
Comment on lines +12 to +15
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { parseEnvFile } from "./lib/env.js";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

fs is imported from node:fs but is never used in this file. If noUnusedLocals is enabled in tsconfig.json, this unused import will cause a compilation error and break the build.

Suggested change
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { parseEnvFile } from "./lib/env.js";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { parseEnvFile } from "./lib/env.js";

Comment thread scripts/deploy-proxy.ts Outdated
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { parseEnvFile, readEnvFileRaw, updateEnvKey } from "./lib/env.js";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

readEnvFileRaw is imported from ./lib/env.js but is never used in this file. If noUnusedLocals is enabled in tsconfig.json, this unused import will cause a compilation error and break the build.

Suggested change
import { parseEnvFile, readEnvFileRaw, updateEnvKey } from "./lib/env.js";
import { parseEnvFile, updateEnvKey } from "./lib/env.js";

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • The reconciliation logic is now split between scripts/reconcile-topology.ts and server/src/services/topologyReconciliation.ts; consider extracting the core drift-detection/redeploy functionality into a shared module so the CLI script and startup hook stay in sync and avoid duplicated behavior.
  • scripts/reconcile-topology.ts declares llmProxyEnvPath and imports fs/llmProxyRoot without using them; cleaning up these unused variables/imports will make the script easier to maintain.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The reconciliation logic is now split between `scripts/reconcile-topology.ts` and `server/src/services/topologyReconciliation.ts`; consider extracting the core drift-detection/redeploy functionality into a shared module so the CLI script and startup hook stay in sync and avoid duplicated behavior.
- `scripts/reconcile-topology.ts` declares `llmProxyEnvPath` and imports `fs`/`llmProxyRoot` without using them; cleaning up these unused variables/imports will make the script easier to maintain.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant