12 KiB
12 KiB
Changelog
All notable changes to wpide-server will be documented in this file. Format follows Keep a Changelog; versioning is SemVer.
[0.6.3] — 2026-05-26
Changed
- Request logging back to
!isDev(silent in prod). Was temporarily forced on to debug the live browser-direct tool round-trip with the plugin on Hostinger (see plugin 56.95/56.96). Now that browser-direct is verified end-to-end (744 ms tool round-trip frommersaai.diretenders.com), prod logs go quiet again — every 30s/v1/healthfrom Docker's healthcheck no longer fills the log file.
Kept
- The targeted diagnostic lines added in 0.6.2 stay in for future
support work:
browser-direct: awaiting tool result from browser(orchestrator)browser-direct: tool result TIMED OUT after 90s(orchestrator)tool_result POST received … matched:true|false(runs route) These are low-volume and useful for diagnosing future host quirks.
[0.6.2] — 2026-05-26
Fixed
z.coerce.boolean()read every boolean env var astrue.Boolean("false")istruein JS, soALLOW_INSECURE_TLS=false,REQUIRE_LICENSE=false, andFREE_TIER_ACTIVE=falsewere all silentlytrue. Replaced with aboolish()parser that treats0/false/no/offas false and1/true/yes/onas true. This bit on the first real VPS deploy: TLS verification stayed disabled and license gating would have switched on unexpectedly.
Added
- Production deploy artifacts (
deploy/).vps-bootstrap.sh(Ubuntu prep: update, ufw, base tools) anddocker-compose.coolify.yml(runs the container behind Coolify's existing Traefik proxy on the externalcoolifynetwork, with Let's Encrypt labels). First live deploy: Contabo VPS → Coolify/Traefik →https://api.qbirr.com.
[0.6.1] — 2026-05-26
Fixed
- SSE stream endpoint now sends CORS headers. The
/v1/runs/:id/streamreply is hijacked (raw), so the cors plugin didn't run on it. Addedaccess-control-allow-origin(echoes request origin) so the plugin's browser-directEventSourcecan open the stream cross-origin (browser on the WP site → server on another domain). Without this the browser blocked the stream.
[0.6.0] — 2026-05-25 — Memory, teams, browser-direct tools
Added
- Server-side conversation memory (
orchestrator/memory.ts). Persists each run's user goal + final answer persession_id; recalls the last ~12 turns and merges (de-duplicated) into context on the next run. Runs now have continuity even when the plugin sends little history. (DB migration v3:conversation_turns.) - Multi-tenant teams (
accounts/teams.ts,routes/teams.ts). Orgs + members + roles;POST/GET /v1/teams, member add/remove. A member inherits the org owner's subscription tier (team owner pays once, seats share the tier) — wired intoresolveAccess. (Migration v3:orgs,org_members,subscriptions.org_id.) - Browser-direct tool execution (cap-immune transport, server side).
browser_tools: trueon a run makes the loop emittool_callSSE events and awaitPOST /v1/runs/:id/tool_resultfrom the browser, instead of calling back into the plugin. Removes the long-lived request from the WP host entirely → works on any shared host. Relay mode (plugin callback) remains the default; this is additive. Proven end-to-end via test (tool_call emitted → result posted → run completed using the posted data).
Notes
- The browser-direct plugin JS (browser opens EventSource + runs the tool via admin-ajax + POSTs the result) is the remaining client-side step; the server fully supports it now.
[0.5.0] — 2026-05-25 — SaaS platform foundation
Added
- Accounts & auth. Email+password (scrypt, no native deps), Google +
GitHub OAuth (authorization-code flow), session JWT in an httpOnly
cookie.
/v1/auth/{register,login,logout,me,set-password}and/v1/auth/oauth/:provider/{start,callback}. - Licensing & subscriptions (no credits). Each account gets a license
key + a subscription row (tier
basic|pro|max, status). The run path resolves the license → tier and gates on an active subscription (REQUIRE_LICENSE, default off in dev so local testing needs no account;DEV_DEFAULT_TIERapplies when off). - Model routing by tier (
routing/policy.ts): tier sets the model ceiling — basic→flash, pro→+thinking, max→+pro-max — combined with mode/complexity. Explicit model picks are honored only within the tier, else downgraded. DeepSeekthinkingparam wired through. - Stripe billing (
fetch, no SDK):/v1/billing/{checkout,portal,webhook}with manual webhook signature verification; subscription state mirrored into the DB. Disabled cleanly when keys absent. - Dashboard at
/app: signup/login (email + Google + GitHub), license key with copy, plan + tier picker + manage-billing. Single inline HTML page, no build step. - DB migration v2: users, oauth_identities, licenses, subscriptions, sites (site registry); runs gain user_id/tier/model.
- Deploy:
SETUP.mdoperator checklist,docker-compose.prod.yml+Caddyfile.prodfor a plain VPS (Coolify uses the Dockerfile directly). SQLite on a persistent volume for v1; Postgres is the documented scale-up path.
Notes
- Credits/metering intentionally deferred — access is subscription-gated, tier gates models. Multi-tenant teams, server-side memory, and the browser-direct SSE transport remain as later sub-projects.
[0.4.1] — 2026-05-25
Fixed
- Reasoning rendered one token per line in the chat. The agentic loop
was emitting a
thinkingevent per reasoning token; the plugin relays each as athoughtevent, and the browser appends one list item per thought — so each reasoning token landed on its own line. Now the loop accumulatesreasoning_contentper step and emits a singlethinkingevent when the step's LLM call finishes (matches the local orchestrator's one-thought-per-step model). Content tokens still stream individually into the live bubble.
[0.4.0] — 2026-05-25
Added
- SSE token streaming.
GET /v1/runs/:run_id/streamstreams a run's live events (token,thinking,tool_call,tool_result,status,done,error,end) with?since=<seq>resume. Backed by a per-run event buffer in the registry (addEvent). OpenAIClient.chatStream()— streaming chat completions over fetch: parses SSE token deltas, accumulatescontent/reasoning_content/tool_calls, returns the same shape aschat(). Connect-only retry (safe to retry before any token; never mid-stream).- The agentic loop now uses
chatStreamand emits token/tool events into the run's buffer as they happen.
Fixed
- DeepSeek v4 thinking mode HTTP 400 — the loop now echoes the
assistant message's
reasoning_contentback on the next turn after a tool call, as DeepSeek v4 requires. (chat()andchatStream()both capture the field; the loop re-sends it.)
[0.3.0] — 2026-05-25
Added
- Async run model — removes the synchronous timeout ceiling.
POST /v1/runs/startregisters a run, kicks off the orchestrator in the background, and returns{ run_id, session_id }immediately.GET /v1/runs/:run_id/statusreports live progress (status,steps_done,tools_used,elapsed_ms,partial_content) and the full PHP-shaperesponseonce finished.- In-memory run registry (
src/orchestrator/registry.ts) with a 30-min TTL for finished runs.process_requestshares its step/tool arrays with the registry so status reflects progress as it happens. - Old synchronous
POST /v1/runsretained for non-browser callers.
- Built-in server-side
waittool — lets agents pace long-running diagnostics without a DBSLEEP()(SQLite has none). Handled in-loop, never calls back to the plugin. Max 30s per call. - LLM chat retry hardened: 6 attempts, 20s per-attempt timeout (fails fast on a hung VPN connection and retries), abort/timeout treated as retryable. Step cap raised 25 → 40.
AGENT_STEP tool_call → <name>logged at info level for live flow visibility.
[0.2.1] — 2026-05-25
Added
- xAI (Grok) provider client — OpenAI-compatible base URL
https://api.x.ai/v1. - DeepSeek provider client — base URL
https://api.deepseek.com/v1. - Provider auto-routing in
pickProvider(): explicit override → model-name prefix (deepseek*,grok*,gpt-*) → first configured key (deepseek → xai → openai).defaultModelFor()picks a sane model per provider. ALLOW_INSECURE_TLS(default on in dev) — skips outbound TLS verification for machines behind a VPN/MITM whose root CA Node doesn't trust. Set off in prod.- Tool-manifest sanitizer (
src/tools/manifest.ts) — coerces PHP's empty[]to{}where objects are required and strips null values, so strict validators (DeepSeek) stop rejecting the plugin's 95 tool schemas with HTTP 400. - LLM chat calls now retry up to 3× with backoff on network errors (connect timeout, DNS, TLS) and 5xx/429 — rides through flaky-VPN blips. 4xx are treated as real errors and not retried.
- Detailed logging on tool-exec callback failures (URL, status, headers, body length) to diagnose cross-machine / rewrite issues.
Changed
- Server binds to
0.0.0.0by default (was127.0.0.1) so other LAN machines can reach it. Default port3017. - Default model is now
deepseek-chat.
[0.2.0] — 2026-05-21
Added
GET /root route returns an API directory (name, version, endpoint hints) — friendlier than the previous 404 when poking around in a browser.POST /v1/runs— main orchestrator entrypoint. Accepts{ goal, context, options, tools_manifest, callback_url, callback_secret, license_key, site_url }and returns the exact response shape PHP'swp_ide_process_agentic()uses:{ success, content, tool_results, execution: { run_id, session_id, mode, steps, status_messages, ... }, approval_payload }.GET /v1/runs/:run_id— fetch a stored run record.- Greeting + simple paths fully working. Greetings need no LLM call;
simple invokes OpenAI chat/completions (default
gpt-4o-mini). Agentic path is a placeholder that returns a "step 5" message. - Orchestrator router (
src/orchestrator/router.ts) — port ofWP_IDE_AI_Router::classify; cheap regex/keyword heuristics that pick greeting / simple / agentic without an LLM call. - OpenAI client over fetch (
src/providers/openai.ts) — no SDK dependency. Provider router (src/providers/index.ts) dispatches by model name; Anthropic / xAI plug in here in later steps. - Runs table CRUD (
src/db/runs.ts) — persists every run with status transitions so a future status endpoint can answer "what happened".
Notes
OPENAI_API_KEYis read from.envon boot. Without it the simple path returns a clear actionable error in the standard response shape; the greeting path still works because it doesn't call any LLM.
[0.1.0] — 2026-05-21
Added
- Initial Fastify scaffold (Node 20, TypeScript, ESM).
GET /v1/healthreturns name, version, uptime, Node version, timestamp.- SQLite via
better-sqlite3as the dev database; WAL mode + foreign keys enabled. Postgres URL recognised for later Coolify deploy but not yet wired. - Initial schema:
schema_version,runstables (more added per milestone). - Zod-validated env loader, pino logger, CORS, graceful shutdown.
start-dev.batfor one-command Windows dev startup.Dockerfilefor future Coolify deployment (not used locally).- Optional
Caddyfilefor local TLS viawpide.local.