Skip to content

Guard subscription deploys without cloud credentials#210

Closed
khaliqgant wants to merge 4 commits into
mainfrom
ar-105-deploy-subscription-auth
Closed

Guard subscription deploys without cloud credentials#210
khaliqgant wants to merge 4 commits into
mainfrom
ar-105-deploy-subscription-auth

Conversation

@khaliqgant

Copy link
Copy Markdown
Member

Summary

  • add a deploy screen subscription option that carries useSubscription through the proactive agent draft/persona bundle
  • block deploy before save/upload when subscription credentials are missing for the selected cloud agent
  • show the exact connect command, e.g. agent-relay cloud connect anthropic, inline on the deploy screen
  • add a DOM regression test for the blocked deploy path

Verification

  • npx vitest run --project dom src/renderer/src/components/proactive/ProactiveAgentEditor.dom.test.ts
  • npm run typecheck:web
  • npm run typecheck fails in existing typecheck:node errors on origin/main (examples: src/main/broker.ts, src/main/cloud-agent.ts, src/main/store.ts, existing node tests)

@codeant-ai

codeant-ai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Your free trial PR review limit of 300 PRs has been reached. Please upgrade your plan to continue using CodeAnt AI.

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4d58c49e-3fe5-4df9-aad1-8ae07c00fb27

📥 Commits

Reviewing files that changed from the base of the PR and between 0521b80 and 42f740c.

📒 Files selected for processing (6)
  • src/main/proactive-agent.bundle.ts
  • src/main/proactive-agent.ts
  • src/main/proactive-agent.types.ts
  • src/renderer/src/components/proactive/ProactiveAgentEditor.dom.test.ts
  • src/renderer/src/components/proactive/ProactiveAgentEditor.tsx
  • src/shared/types/ipc.ts

📝 Walkthrough

Walkthrough

This PR extends proactive agent deployment to support user-supplied LLM provider credentials via a new optional useSubscription field. The type contract propagates through draft normalization and persona spec generation, while the editor validates credential presence before deployment and surfaces UI guidance for users selecting subscription mode.

Changes

Subscription-based proactive agent deployment with credential gating

Layer / File(s) Summary
Type contract propagation
src/shared/types/ipc.ts, src/main/proactive-agent.types.ts, src/main/proactive-agent.bundle.ts
ProactiveAgentDraft gains optional useSubscription?: boolean field across the IPC contract, local type definitions, and bundled PersonaSpecJson.
Draft normalization and persona spec building
src/main/proactive-agent.ts, src/main/proactive-agent.bundle.ts
normalizeDraft and buildPersonaSpec now propagate useSubscription through the normalization and spec-generation pipeline.
Editor deployment credential gating
src/renderer/src/components/proactive/ProactiveAgentEditor.tsx
Helper functions derive provider type and build credential connection commands; memoized values cache selected cloud agent and subscription state; early deployment guard blocks creation when useSubscription is true but credentials are missing; draft normalization preserves the field.
Subscription UI and credential warnings
src/renderer/src/components/proactive/ProactiveAgentEditor.tsx
Added "Use my subscription" checkbox with conditional warning callouts that guide users to connect LLM provider credentials when subscription mode is selected.
Credential blocking validation test
src/renderer/src/components/proactive/ProactiveAgentEditor.dom.test.ts
DOM test verifies deployment is blocked with error messaging when subscription mode is enabled but LLM provider credentials are absent.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A subscription flag hops in to play,
Credentials checked before deploy's way,
The rabbit guards the agent's faithful leap,
With type contracts safe and warnings deep! 🚀✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Guard subscription deploys without cloud credentials' directly and clearly describes the main change: adding credential gating to block proactive agent deployments when using subscription mode without connected cloud provider credentials.
Description check ✅ Passed The description provides a clear and specific explanation of the changes: adding a subscription option, blocking deploys without credentials, showing connect commands, and adding tests. It is directly related to the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ar-105-deploy-subscription-auth

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@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 'useSubscription' option for proactive agents, allowing users to run inference using their own connected LLM provider credentials. It updates the agent manager, types, and editor UI to support this toggle, and implements validation to block deployment with a helpful connection command if credentials are missing. A new DOM test suite is also added to verify this deployment guard. The reviewer suggested refactoring the 'subscriptionProviderForDraft' helper function in 'ProactiveAgentEditor.tsx' to use a more data-driven mapping approach and eliminate redundant code.

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 +226 to +237
function subscriptionProviderForDraft(draft: ProactiveAgentDraft): string {
const model = draft.model.trim().toLowerCase()
if (/(anthropic|claude)/.test(model)) return 'anthropic'
if (/(openai|codex|gpt)/.test(model)) return 'openai'
if (/(google|gemini)/.test(model)) return 'google'
if (/(openrouter|opencode)/.test(model)) return 'openrouter'

if (draft.harness === 'claude') return 'anthropic'
if (draft.harness === 'codex') return 'openai'
if (draft.harness === 'opencode') return 'openrouter'
return draft.harness
}

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

This function can be refactored to be more data-driven and avoid repetition, which will make it easier to maintain and extend in the future. You can use maps for model-to-provider and harness-to-provider lookups. Also, the final return draft.harness is currently unreachable because all possible values of draft.harness are handled by the preceding if statements.

function subscriptionProviderForDraft(draft: ProactiveAgentDraft): string {
  const model = draft.model.trim().toLowerCase()

  const modelProviderMap: Array<[RegExp, string]> = [
    [/(anthropic|claude)/, 'anthropic'],
    [/(openai|codex|gpt)/, 'openai'],
    [/(google|gemini)/, 'google'],
    [/(openrouter|opencode)/, 'openrouter']
  ]

  for (const [regex, provider] of modelProviderMap) {
    if (regex.test(model)) return provider
  }

  const harnessProviderMap: Record<Harness, string> = {
    claude: 'anthropic',
    codex: 'openai',
    opencode: 'openrouter'
  }

  return harnessProviderMap[draft.harness]
}

@codeant-ai

codeant-ai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Your free trial PR review limit of 300 PRs has been reached. Please upgrade your plan to continue using CodeAnt AI.

@khaliqgant khaliqgant left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Code Review: AR-105 — Guard subscription deploys without cloud credentials

Verdict: LGTM — the core behavior is correct on all four criteria. Three minor points below; none block merge.


Checklist

Check Result
Credentials-absent condition correctly detected
Deploy actually blocked (not just a warning)
Command is accurate and copy-paste ready ✅ (see note #3)
Guard only triggers on subscription selection

✅ Deploy is genuinely blocked

handleDeploy returns after setErrors({ deploy: subscriptionBlock }), before saveDraft() or proactiveAgent.deploy() are ever reached. createMock and deployMock stay uncalled — confirmed by the DOM test.


Minor comment 1 — markPhase('bundle', 'error') before markPhase('bundle', 'active')

// ProactiveAgentEditor.tsx ~L774
const subscriptionBlock = subscriptionCredentialBlockMessage(selectedDraft, cloudAgents)
if (subscriptionBlock) {
  setErrors({ deploy: subscriptionBlock })
  markPhase('bundle', 'error')   // ← bundle was never 'active'
  return
}

Bundle transitions directly to error without ever being active. The phase UI will show bundle as crashed-from-the-start rather than a pre-flight block. Recommend either omitting the markPhase call here (the errors.deploy message is sufficient), or adding a dedicated credentials phase for this pre-bundle check.


Minor comment 2 — lastAuthenticatedAt as the credential proxy

CloudAgentRecord.lastAuthenticatedAt is a generic timestamp with no guarantee it's cleared when provider credentials are revoked or expire. If the backend only sets this once at creation, a user with expired credentials would pass the guard. If this is the intended/correct signal, a short inline comment near subscriptionCredentialBlockMessage stating the assumption would prevent future confusion (e.g. "null = no credentials have been connected; backend nulls this on revocation").


Minor comment 3 — Verbatim harness fallback in subscriptionProviderForDraft

// ProactiveAgentEditor.tsx ~L230
return draft.harness   // ← could be 'custom', '', 'gemini-pro', etc.

If draft.harness is an unrecognized value the generated command becomes agent-relay cloud connect <arbitrary>. Suggest either adding a 'gemini''google' mapping if the Google harness is used, or falling back to the literal string '<provider>' so it's obvious the command needs editing rather than silently wrong.


DOM test

Correctly verifies the inline warning appears before Deploy and the error is set on Deploy without calling create/deploy. One robustness note: the pre-click getAllByText(...) assertion runs synchronously — if the inline warning render is ever async it could flake. Wrapping in waitFor would make it more resilient.


Overall this is clean. Blocking logic is sound and the two-level UX (inline warning + deploy-time error) is the right approach.

@codeant-ai

codeant-ai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Your free trial PR review limit of 300 PRs has been reached. Please upgrade your plan to continue using CodeAnt AI.

@codeant-ai

codeant-ai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Your free trial PR review limit of 300 PRs has been reached. Please upgrade your plan to continue using CodeAnt AI.

@khaliqgant

Copy link
Copy Markdown
Member Author

Closing per dispatcher instruction: AR-105 belongs in AgentWorkforce/cloud, not pear. This PR will not be merged.

@khaliqgant khaliqgant closed this Jun 10, 2026
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