Skip to content

Add deployment provider credential routing - #4557

Closed
dredozubov wants to merge 84 commits into
nexu-io:mainfrom
dredozubov:provider-orchestrator-runtime
Closed

Add deployment provider credential routing#4557
dredozubov wants to merge 84 commits into
nexu-io:mainfrom
dredozubov:provider-orchestrator-runtime

Conversation

@dredozubov

@dredozubov dredozubov commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Why

Some self-host deployments manage provider credentials and provider policy server-side through an OpenAI-compatible gateway. Open Design already supports direct BYOK, but deployments with shared credential custody need one daemon-owned credential source that behaves consistently across model discovery, connection tests, proxy chat, finalize, headless inspection, and first-run setup.

Support first-run setup when an administrator has preconfigured a deployment provider. The browser can read only redacted provider availability metadata; credentials remain daemon-side.

This keeps AMR, local CLI, and direct BYOK unchanged. When no deployment provider environment is configured, existing users keep the current behavior.

What users will see

Existing deployment-backed API, CLI, and web provider flows work without client-side credentials or repeated endpoint setup. Self-hosted operators can route OpenAI-compatible credentials and optional run-session metadata through the daemon.

On first run, if an administrator has configured a deployment provider, the onboarding Connect step can offer that provider as a ready-to-use option. The user sees the configured label/host and chooses a model, but never sees or enters the deployment credential.

What changed

  • Add a shared credentialSource contract field. The default is user, preserving the existing direct BYOK request shape.
  • Add credentialSource: "deployment" for daemon-resolved OpenAI-compatible provider credentials.
  • Add a redacted /api/provider-orchestrator/config status endpoint and od provider config CLI mirror. They report availability, label, display host, default model, and failure kind, but never return the credential.
  • Allow the browser to read that redacted provider status so first-run onboarding can use administrator-managed provider setup without exposing credentials.
  • Apply the same deployment credential resolution to provider model discovery, connection tests, OpenAI-compatible proxy chat, and finalize/provider calls.
  • Ignore caller-supplied apiKey and baseUrl when deployment credentials are selected; the daemon resolves and validates the configured endpoint instead.
  • Support optional daemon-side run-session bootstrap metadata for deployments that need a per-run authorization record before provider egress.
  • Add web request-shape support for existing deployment-sourced config and first-run selection.
  • Document the deployment env vars for self-host operators.

Surface area

  • UI — new page / dialog / panel / menu item / setting / empty state in apps/web or apps/desktop (including Electron menu bar)
  • Keyboard shortcut — new or changed
  • CLI / env var — new od subcommand or flag, new tools-dev / tools-pack / tools-pr flag, or new OD_* env var
  • API / contract — new /api/* endpoint, new SSE event, or changed shape in packages/contracts
  • Extension point — new entry under skills/, design-systems, design-templates, or craft/, or change to the skills protocol
  • i18n keys — added new translation keys (see TRANSLATIONS.md for the locale workflow)
  • New top-level dependency — adding any new entry to the root package.json (dependencies or devDependencies)
  • Default behavior change — changes what existing users experience without opting in
  • None — internal refactor, docs, tests, or translation update only

Screenshots

Deployment-provider UI screenshots were added in the PR thread:

Non-goals

  • No AMR behavior changes.
  • No direct BYOK behavior changes.
  • No support for non-OpenAI-compatible deployment provider protocols.

Validation

Ran with Node 24.12.0:

  • pnpm exec vitest run -c vitest.config.ts tests/finalize-design.test.ts -t "ignores caller baseUrl validation" from apps/daemon
  • pnpm exec vitest run -c vitest.config.ts tests/api-token-guard.test.ts -t "opens only redacted deployment provider discovery" from apps/daemon
  • pnpm exec vitest run -c vitest.config.ts tests/components/EntryShell.onboarding.test.tsx -t "continues with an available deployment provider" from apps/web
  • pnpm --filter @open-design/web typecheck
  • pnpm --filter @open-design/daemon typecheck
  • pnpm guard

Earlier validation on this PR also covered:

  • pnpm --filter @open-design/web exec vitest run tests/providers/api-proxy.test.ts tests/lib/resolve-finalize-request.test.ts tests/components/InlineModelSwitcher.test.tsx
  • pnpm --filter @open-design/daemon exec vitest run tests/cli-startup.test.ts tests/connection-test.test.ts tests/proxy-routes.test.ts tests/finalize-design.test.ts
  • pnpm --filter @open-design/contracts typecheck
  • pnpm typecheck

@lefarcen
lefarcen requested review from free666799 and nettee June 21, 2026 07:34
@lefarcen lefarcen added size/XXL PR changes 1500+ lines risk/high High risk: apps/desktop, daemon, auth, migration, workflows, package deps type/feature New feature needs-validation Runtime change detected; needs human or /explore agent validation. labels Jun 21, 2026
@lefarcen

Copy link
Copy Markdown
Contributor

Hey @dredozubov — the rationale and validation notes here are helpful. One quick PR-body follow-up before pool review: could you add a short What users will see section from the user's point of view, even if the answer is mainly "existing deployment-backed API flows work without client-side credentials or repeated endpoint setup"?

Also, this PR touches behavior that will need a manual QA pass before merge, so please hold off self-merging for now — we'll loop QA in once it's merge-ready (and after the required product sign-off on this head).

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Two blocking issues showed up in the new deployment-provider path.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/daemon/src/import-export-routes.ts
Comment thread apps/daemon/src/routes/chat.ts Outdated

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Two blocking issues are still present in the deployment-provider path on the current head.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Location: apps/daemon/src/chat-routes.ts RIGHT line 150

deploymentProviderRunMetadata() now sits directly on the /api/proxy/openai/stream request path, but this bootstrap call still does a raw fetch() with no abort signal, no bounded timeout, and no proxyDispatcherRequestInit. That means a slow run-session service can stall the chat request before SSE starts, and deployments that require the configured outbound proxy for provider egress can fail here even though the actual provider call would succeed. Please thread request cancellation and a timeout into this helper, send it through the same proxy dispatcher used for provider egress, and add coverage for a stalled or proxy-routed run-session endpoint.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Inline comment could not be anchored: inline anchor is outside the PR diff anchorable ranges

Comment thread apps/daemon/src/import-export-routes.ts

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Two blocking correctness issues are still present in the deployment-provider path.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/web/src/providers/api-proxy.ts
Comment thread apps/daemon/src/deployment-provider.ts

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One blocking issue remains in the deployment-provider validation path.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/daemon/src/deployment-provider.ts Outdated
@lefarcen

Copy link
Copy Markdown
Contributor

Hey @dredozubov — the latest current-head blocker from @nettee looks narrower than the earlier deployment-provider passes: the Kimi direct -p ... --output-format stream-json switch dropped the ACP-side MCP wiring on this head, so the runtime no longer carries the live-artifacts server or user-configured external MCP servers.

I'd drive that review thread next before anything else.

@dredozubov

Copy link
Copy Markdown
Contributor Author

Pushed b97dc14ab to address the Kimi direct-mode MCP review thread.

What changed:

  • Keeps Kimi on direct -p ... --output-format stream-json mode, but documents that this path does not expose the ACP mcpServers descriptor.
  • Pins Kimi runtime coverage so it no longer advertises mcpDiscovery / externalMcpInjection while direct mode is active.
  • Updates prompt-budget coverage for Kimi argv prompt limits.

Validation run locally under the available Node 26 shell (repo warns it wants Node ~24):

  • pnpm --filter @open-design/daemon exec vitest run tests/runtimes/agent-args.test.ts tests/runtimes/prompt-budget.test.ts tests/runtimes/mcp.test.ts
  • pnpm --filter @open-design/daemon exec vitest run tests/connection-test.test.ts -t "launches Kimi connection tests without the legacy acp positional arg"
  • pnpm --filter @open-design/daemon typecheck
  • pnpm guard

Read-only cross-review found no remaining accepted blocker in the pushed diff.

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@dredozubov I re-checked the current head with focus on the changed ranges on b97dc14ab0187a4c692257bdf29dba2885114d0d: the Kimi direct-mode runtime follow-up in apps/daemon/src/runtimes/defs/kimi.ts, the matching MCP/prompt-budget/runtime coverage, and the surrounding deployment-provider routing, contract, and web follow-through that remained in scope on this head. Those deltas line up with the earlier review feedback, and I didn’t find any new actionable issues in the current changed ranges. I wasn’t able to execute the local Vitest or typecheck slices in this worktree because node_modules / vitest are not installed here, but the code and targeted test updates are internally consistent. Nice work closing out the Kimi follow-up without re-opening the deployment-provider regressions.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

@dredozubov

Copy link
Copy Markdown
Contributor Author

Maintenance pass on current head b97dc14ab:

  • GitHub reports the branch is mergeable, and all current head CI check-runs are green.
  • Review threads are all resolved.
  • Latest current-head code review from @nettee is approved.
  • I did not push code changes in this pass.

Remaining blockers look external to the branch diff: GitHub still reports reviewDecision: CHANGES_REQUESTED / mergeStateStatus: BLOCKED, and the PR still carries needs-design-review + needs-validation. Could a maintainer/design/QA owner clear or re-check those if this branch is still the intended merge path? #5257 is the clean approved fallback path and is currently queued for manual QA.

@lefarcen

Copy link
Copy Markdown
Contributor

Hey @dredozubov — thanks for the state check. I re-checked the current PR state on this head: product is already signed off, and the remaining gate on this branch is still design (needs-design-review is present and design-approved hasn't landed yet), so QA stays parked behind that for now.

I've re-routed the design check on this head. If this branch stays the intended merge path once design clears, QA can pick it up from there.

@open-design-crew open-design-crew Bot added the design-approved Design signed off (must be applied by the Odcrew App open-design-crew[bot]) label Jul 13, 2026
@lefarcen lefarcen removed the needs-design-review Awaiting design review (external UI change); cleared by the Odcrew App applying design-approved label Jul 13, 2026

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I found one blocking regression in the onboarding deployment-provider flow.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/web/src/components/EntryShell.tsx Outdated
@lefarcen

Copy link
Copy Markdown
Contributor

Hey @dredozubov@nettee’s latest current-head review is the one to drive next.

From the scoped onboarding/settings diff on this head, the blocker looks narrowly focused on the config-persist path: failed deployment-provider saves still need to surface as failures instead of letting onboarding continue as if the write succeeded.

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I found one non-blocking follow-up in the deployment-provider model-list invalidation path.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/web/src/components/providerModelsCache.ts
@lefarcen
lefarcen requested a review from nettee July 18, 2026 13:28

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@dredozubov I re-checked the current head with focus on the deployment credential-routing changes in the daemon, the redacted /api/provider-orchestrator/config plus od provider config surfaces, the run-session plumbing across model discovery / connection test / proxy / finalize, and the onboarding/settings/model-switcher follow-through in the web app. The changed ranges line up with the prior review history and the added regression coverage, and I didn’t find any new actionable issues on 068a69753c4274c76e5b1b95a58a96b9571ea612. I wasn’t able to execute the local Vitest or typecheck slices in this worktree because node_modules are not installed here, but the current code and targeted tests are internally consistent. Nice work closing out the deployment-provider flow while keeping browser-visible state redacted.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I found one non-blocking follow-up in the deployment-provider connection-test path.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/daemon/src/connectionTest.ts Outdated

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@dredozubov I re-checked the current head with focus on the changed deployment credential-routing surface: the daemon-side deployment provider resolution and optional run-session bootstrap, the redacted /api/provider-orchestrator/config plus od provider config mirror, the model-discovery / connection-test / proxy / finalize plumbing, and the onboarding/settings/model-switcher follow-through in the web app. The current changed ranges line up with the prior review history and the added regression coverage, and I didn’t find any new actionable issues on b4712fa6c294c08986c1ae96edf96e7536d44bea. Nice work closing out the deployment-provider flow while keeping browser-visible state redacted.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

@nettee nettee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

One blocking regression remains in the current head.

🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.

Comment thread apps/web/src/components/InlineModelSwitcher.tsx Outdated
@lefarcen
lefarcen requested a review from nettee July 21, 2026 11:51
@dredozubov

Copy link
Copy Markdown
Contributor Author

Closing as superseded by #5257. The compatible #4557 follow-ups are now in #5257 at 197eaf4 (deployment onboarding save-failure gate, topbar model switcher visibility fix, and test stabilization). #5257 deliberately retains the deployment credential routing and Kimi ACP runtime policy, so the direct-Kimi divergence from this branch is not carried forward.

@dredozubov dredozubov closed this Jul 22, 2026
@lefarcen

Copy link
Copy Markdown
Contributor

Thanks for closing the loop and for linking #5257.

We'll treat this branch as superseded and follow the compatible deployment-provider follow-ups there.

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

Labels

design-approved Design signed off (must be applied by the Odcrew App open-design-crew[bot]) needs-validation Runtime change detected; needs human or /explore agent validation. risk/high High risk: apps/desktop, daemon, auth, migration, workflows, package deps size/XXL PR changes 1500+ lines type/feature New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants