diff --git a/extensions/positron-assistant/package.json b/extensions/positron-assistant/package.json index b71c74907db5..c5e85cd3835c 100644 --- a/extensions/positron-assistant/package.json +++ b/extensions/positron-assistant/package.json @@ -473,6 +473,11 @@ "default": "", "markdownDescription": "%configuration.models.preference.snowflakeCortex.description%" }, + "positron.assistant.models.preference.msFoundry": { + "type": "string", + "default": "", + "markdownDescription": "%configuration.models.preference.msFoundry.description%" + }, "positron.assistant.models.preference.openAI": { "type": "string", "default": "", @@ -486,18 +491,7 @@ "positron.assistant.models.preference.positAI": { "type": "string", "default": "", - "markdownDescription": "%configuration.models.preference.positAI.description%", - "tags": [ - "advanced" - ] - }, - "positron.assistant.models.preference.msFoundry": { - "type": "string", - "default": "", - "markdownDescription": "%configuration.models.preference.msFoundry.description%", - "tags": [ - "advanced" - ] + "markdownDescription": "%configuration.models.preference.positAI.description%" }, "positron.assistant.models.preference.google": { "type": "string", @@ -633,10 +627,10 @@ ] ] }, - "positron.assistant.models.overrides.openAI": { + "positron.assistant.models.overrides.msFoundry": { "type": "array", "default": [], - "markdownDescription": "%configuration.models.overrides.openAI.description%", + "markdownDescription": "%configuration.models.overrides.msFoundry.description%", "items": { "type": "object", "properties": { @@ -663,20 +657,12 @@ "name", "identifier" ] - }, - "examples": [ - [ - { - "name": "GPT-4o", - "identifier": "gpt-4o" - } - ] - ] + } }, - "positron.assistant.models.overrides.customProvider": { + "positron.assistant.models.overrides.openAI": { "type": "array", "default": [], - "markdownDescription": "%configuration.models.overrides.customProvider.description%", + "markdownDescription": "%configuration.models.overrides.openAI.description%", "items": { "type": "object", "properties": { @@ -707,21 +693,16 @@ "examples": [ [ { - "name": "Claude Sonnet 4.5 via OpenRouter", - "identifier": "anthropic/claude-sonnet-4.5", - "maxInputTokens": 200000, - "maxOutputTokens": 8192 + "name": "GPT-4o", + "identifier": "gpt-4o" } ] ] }, - "positron.assistant.models.overrides.positAI": { + "positron.assistant.models.overrides.customProvider": { "type": "array", "default": [], - "markdownDescription": "%configuration.models.overrides.positAI.description%", - "tags": [ - "advanced" - ], + "markdownDescription": "%configuration.models.overrides.customProvider.description%", "items": { "type": "object", "properties": { @@ -748,15 +729,22 @@ "name", "identifier" ] - } + }, + "examples": [ + [ + { + "name": "Claude Sonnet 4.5 via OpenRouter", + "identifier": "anthropic/claude-sonnet-4.5", + "maxInputTokens": 200000, + "maxOutputTokens": 8192 + } + ] + ] }, - "positron.assistant.models.overrides.msFoundry": { + "positron.assistant.models.overrides.positAI": { "type": "array", "default": [], - "markdownDescription": "%configuration.models.overrides.msFoundry.description%", - "tags": [ - "advanced" - ], + "markdownDescription": "%configuration.models.overrides.positAI.description%", "items": { "type": "object", "properties": { @@ -843,31 +831,31 @@ }, "positron.assistant.provider.amazonBedrock.enable": { "type": "boolean", - "default": false, + "default": true, "markdownDescription": "%configuration.provider.amazonBedrock.enable.description%", - "tags": [ - "preview" - ], "order": 3 }, "positron.assistant.provider.snowflakeCortex.enable": { "type": "boolean", - "default": false, + "default": true, "markdownDescription": "%configuration.provider.snowflakeCortex.enable.description%", - "tags": [ - "preview" - ], "order": 4 }, - "positron.assistant.provider.openAI.enable": { + "positron.assistant.provider.msFoundry.enable": { "type": "boolean", "default": false, - "markdownDescription": "%configuration.provider.openAI.enable.description%", + "markdownDescription": "%configuration.provider.msFoundry.enable.description%", "tags": [ "preview" ], "order": 5 }, + "positron.assistant.provider.openAI.enable": { + "type": "boolean", + "default": true, + "markdownDescription": "%configuration.provider.openAI.enable.description%", + "order": 6 + }, "positron.assistant.provider.customProvider.enable": { "type": "boolean", "default": false, @@ -875,25 +863,14 @@ "tags": [ "experimental" ], - "order": 6 + "order": 7 }, "positron.assistant.provider.positAI.enable": { "type": "boolean", - "default": false, + "default": true, "markdownDescription": "%configuration.provider.positAI.enable.description%", "tags": [ - "experimental", - "advanced" - ], - "order": 7 - }, - "positron.assistant.provider.msFoundry.enable": { - "type": "boolean", - "default": false, - "markdownDescription": "%configuration.provider.msFoundry.enable.description%", - "tags": [ - "experimental", - "advanced" + "preview" ], "order": 8 }, diff --git a/extensions/positron-assistant/src/extension.ts b/extensions/positron-assistant/src/extension.ts index 4a0da346eec7..b85754a529b2 100644 --- a/extensions/positron-assistant/src/extension.ts +++ b/extensions/positron-assistant/src/extension.ts @@ -249,10 +249,64 @@ async function initializeProviderConfiguration(context: vscode.ExtensionContext) // 2. Perform settings migrations (provider enablement, model preferences, custom models) await performSettingsMigrations(); - // 3. Validate that at least one provider is enabled + // 3. Apply PWB-specific provider defaults + await applyPwbProviderDefaults(context); + + // 4. Validate that at least one provider is enabled await validateProvidersEnabled(); } +/** + * Apply PWB-specific provider defaults. + * + * On Posit Workbench, Posit AI should default to disabled, but users and admins + * can still configure it. Since package.json doesn't support conditional defaults, + * we use globalState to track whether we've applied the PWB default. This ensures: + * - First run on PWB: Posit AI is disabled (unless already configured) + * - Admin configures via policy: their choice is respected because we can't overwrite admin policies + * - User changes the setting: their choice is preserved + * - Subsequent runs: we don't overwrite existing choices + * + * See: https://github.com/posit-dev/positron/issues/12954 + */ +async function applyPwbProviderDefaults(context: vscode.ExtensionContext): Promise { + if (!IS_RUNNING_ON_PWB) { + return; + } + + const pwbDefaultAppliedKey = 'positAI.pwbDefaultApplied'; + const pwbDefaultApplied = context.globalState.get(pwbDefaultAppliedKey); + + if (!pwbDefaultApplied) { + const config = vscode.workspace.getConfiguration('positron.assistant.provider.positAI'); + const currentValue = config.get('enable'); + + // If already disabled (by admin policy, user, or any other means), nothing to do + if (currentValue !== false) { + const enableInspect = config.inspect('enable'); + + // Only apply default if no one has explicitly configured this setting. + // Admin policy values aren't exposed via inspect(), but if an admin + // enforced a policy, the update will fail and we catch it below. + const hasExplicitValue = enableInspect?.globalValue !== undefined || + enableInspect?.workspaceValue !== undefined || + enableInspect?.workspaceFolderValue !== undefined; + + if (!hasExplicitValue) { + try { + await config.update('enable', false, vscode.ConfigurationTarget.Global); + } catch (e) { + // Setting may be enforced by admin policy; log and continue + log.warn(`Posit AI enablement enforced by admin policy and cannot be updated: ${e instanceof Error ? e.message : String(e)}`); + } + } + } + + // Always mark as applied so we don't retry + await context.globalState.update(pwbDefaultAppliedKey, true); + } +} + async function reconcileAuthProviderModels( context: vscode.ExtensionContext, providerId: string,