feat(server,app): gateway-style server-side provider sync on the local server - #3526
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
Photo roll — granted-cloud-providers-appear-automatically-in-settings-and-the-model-picker — 2/2 frames passed · 2 facts✅ 2/2 frames passed · 2 facts · 8 expectations passed · 0 failed ℹ️ FACT — 1. The granted provider connected without an import actionSettings state: {"connected":true,"importButton":false}
✅ PASS — 2. The Cloud providers page shows Automatic Team Models as Connected
ℹ️ FACT — 3. The automatically imported provider contributes its modelSelectable models: [{"id":"automatic-proof-model","name":"Automatic Proof Model","providerName":"Automatic Team Models","selected":false,"selectable":true}]
✅ PASS — 4. The open Models picker shows automatic-proof-model from the organization provider
Roll created 2026-08-05T10:56:06.301Z · Source: |
dff3e3a to
79e658e
Compare
…ocal workspaces Rebuilt on dev after #3525 (status-only settings, renderer auto-sync). The local OpenWork server now materializes org (Den) LLM providers itself, mirroring den-api's cloud worker materializer: the app hands it the Den session (PUT/DELETE /den-session with the resolved API base), the server pulls providers and writes them engine-global with env + engine auth delivery, fingerprint-cached, swept on sign-out, reconciled on an interval plus run-now pings. GET /capabilities advertises providerSync; when the renderer sees it (and holds a host token) it skips client-side materialization — the same handled_server_side outcome gateway mode uses — and reads imported state from GET /cloud-provider-sync/status. Stale renderer-era per-workspace lpr_* rows and cloudImports baselines are cleared so they cannot shadow the fresh global layer. The renderer path from #3525 remains the fallback for servers without the capability.
79e658e to
c9187aa
Compare
There was a problem hiding this comment.
Warden security clearance: clear. No new security issues found in this diff (c9187aa48ac31d68f18ee431fc7bd38ed0fe7a79). Automated clearance satisfies the required-review gate only — a human still reviews and merges. Analysis run


What
Rebuilt on
devafter #3525 merged — single commit on top of it. #3525 removed the Import concept but kept materialization in the renderer; this PR moves it server-side for local workspaces, the same way gateway/cloud instances work: the server materializes, the client displays.Server (
apps/server)cloud-provider-sync.ts— local sibling of den-api's cloud worker materializer (ported pure logic; never importsee/**):GET /v1/llm-providers,GET /v1/llm-providers/:id/connect; Bearer + org header; bounded fetches).syncManagedProviderAuth.owp:v1:fingerprint noop-cache; serialized passes; 5-min interval (env-overridable) + run-now.lpr_*rows andopenwork.cloudImports.providersbaselines are cleared so they can't shadow the fresh global layer.PUT/DELETE /den-session(host-token; body carries the resolved Den API base),POST /cloud-provider-sync/run(host-token),GET /cloud-provider-sync/status(client).GET /capabilitiesadvertisesproviderSync: true.no_session(push + one retry).App (
apps/app) — minimal delta on #3525's merged storeproviderSyncand the app holds its host token: sync triggers ping run-now and return the samehandled_server_sideoutcome gateway mode uses;refreshImportedCloudProvidersreads the status endpoint, feeding feat(app): auto-import granted cloud providers — remove the Import button, status-only settings #3525's status-only rows ("Connected") with zero view changes.lastSyncError, and conflict terminality are untouched and remain the fallback for servers without the capability. Gateway short-circuit unchanged.Evidence
evals/specs/cloud-provider-auto-import.slow.test.ts(feat(app): auto-import granted cloud providers — remove the Import button, status-only settings #3525's own demo — member sees Connected, no Import button, models in the picker) passes unchanged on this branch against a cold local Den + Electron (tape published below).den_request_failed_404— an error string that exists only in the new server module — confirming capability → session push → run-now → server Den client end-to-end; the only change before green was fixing the pushed base URL to the resolved/api/denAPI base (that fix ships here, with a unit test pinning the pushed URL).cloud-provider-sync.e2e.test.ts(realstartServer, fake Den): apply/noop fingerprint, drift rewrite, upstream removal, per-workspace takeover cleanup, sign-out sweep,no_session, Den-failure reporting, status shape.no_sessionpush-retry with the/api/denbase asserted, failure mapping, status→importedCloudProvidersmapping; all feat(app): auto-import granted cloud providers — remove the Import button, status-only settings #3525 tests pass unchanged.Tests run
apps/server:bun test src/— 629 pass, 2 skip, 0 fail ·pnpm typecheckpassapps/app:bun test --isolate(sync-gateway, sync-triggers, reimport, credentials, cloud-providers-view, composer-model-controls) — 34 pass, 0 fail ·pnpm typecheckpassOPENWORK_EVAL_APP_SPECS=1 vitest --project stack specs/cloud-provider-auto-import.slow.test.ts— passed (96s, cold localserver()+ Docker MySQL)Notes for review
lastSyncErrorstays empty; a persistent server-side Den failure is visible via the status endpoint'slastRunand surfaces asproviderAuthErroron settings open — richer per-provider mapping is a natural follow-up.