Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 41 additions & 64 deletions extensions/positron-assistant/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "",
Expand All @@ -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",
Expand Down Expand Up @@ -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": {
Expand All @@ -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": {
Expand Down Expand Up @@ -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": {
Expand All @@ -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": {
Expand Down Expand Up @@ -843,57 +831,46 @@
},
"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,
"markdownDescription": "%configuration.provider.customProvider.enable.description%",
"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
},
Expand Down
56 changes: 55 additions & 1 deletion extensions/positron-assistant/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<void> {
if (!IS_RUNNING_ON_PWB) {
return;
}

const pwbDefaultAppliedKey = 'positAI.pwbDefaultApplied';
const pwbDefaultApplied = context.globalState.get<boolean>(pwbDefaultAppliedKey);

if (!pwbDefaultApplied) {
const config = vscode.workspace.getConfiguration('positron.assistant.provider.positAI');
const currentValue = config.get<boolean>('enable');

// If already disabled (by admin policy, user, or any other means), nothing to do
if (currentValue !== false) {
const enableInspect = config.inspect<boolean>('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,
Expand Down
Loading